本地类中的成员模板

55

给定以下代码:

void f()
{
    class A
    {
        template <typename T>
        void g() {}
    };
}

g++ 4.4(以及 g++-4.6 -std = gnu ++0x )抱怨:“局部类中的成员模板声明无效。”

显然,不允许局部类具有模板成员。这个限制的目的是什么?它会在C++0x中被移除吗?

注意:如果我使局部类本身成为模板,而不是给它一个模板成员:

<code>void f()
{
    template <typename T>
    class A
    {
        void g() {}
    };
}
</code>

我收到了"error: a template declaration cannot appear at block scope" 的错误提示。


1
我在与g++-4.6的斗争中遇到了这个老问题。它仍然在抱怨,所以我稍微编辑了一下这个问题。希望我们能得到更多的答案! - Aaron McDaid
@AaronMcDaid:不幸的是,目前没有更多可以说的了。正如litb在他对Crazy Eddie答案的评论中指出的那样,C++11 没有为本地类添加支持,这些类是模板或具有模板成员(它添加了将本地类用作另一个(非本地)类的模板参数的支持,但这是一个不同的特性)。因此,预计g++在不久的将来不会支持此功能,除非作为编译器扩展。我认为这很遗憾,因为它本来是一个有用的功能,但是嘿,总还有C++24... - HighCommander4
C++14允许使用可变参数定义本地通用Lambda。它们非常接近于模板,因此可能是一种适合的解决方法。 - Aaron McDaid
@HighCommander4,现在是2022年,但仍不支持。 - Rohan Bari
1个回答

11

这个限制的目的?仅仅是一个猜测,但可能有以下原因:

  • 只能在封闭函数内使用模板类/模板成员函数。因此,您已经知道函数中使用的所有类型,因此可以直接指定所使用的类型(对于多种类型,当然,模板变体可以节省一些打字)。
  • 尽管看起来可能不是这样,但这对于所有编译器创建者来说都是工作量,并且还会增加错误的空间,因此必须值得这样做。

有趣的事实:尝试在函数中将局部类用作(c++0x)lambda函数的返回类型:MSVC 2010:内部编译器错误^^。


4
你可能知道所使用的类型,但仍然需要使用 SFINAE 技巧来避免暴露辅助结构体。 - riv
5
实际上,当本地类是作为访问者与 boost::variant 一起使用 boost::apply_visitor 时,你并不知道类型。 - Giel
5
如果函数本身是一个模板,你也不知道所涉及的类型。这个限制很可能是为了让编译器的编写更容易,尽管我无法理解为什么会这样。应该可以重用非局部模板的代码。 - Adrian
这并没有意义,因为你可能知道哪些函数是必需的,但你仍然需要手动编写它们。 - Bonita Montero

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接