本地班级成员模板

问题描述 投票:0回答:2

给出以下代码:

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

g++ 4.4(还有

g++-4.6 -std=gnu++0x
)抱怨:“本地类中成员模板的声明无效”。

显然本地类不允许有模板成员。这个限制的目的是什么?在C++0x中会被删除吗?

注意:如果我将本地类本身设为模板,而不是为其提供模板成员:

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

我收到“错误:模板声明不能出现在块作用域”。

c++ templates c++11 local-class
2个回答
11
投票

这个限制的目的是什么?只是猜测,但是:

  • 您只能在封闭函数中使用模板类/模板成员函数。因此,您已经知道函数中所有使用的类型,因此可以直接指定使用的类型(当然,对于多种类型,模板变体将节省一些输入)。
  • 尽管看起来可能并非如此,但它对所有编译器创建者来说都是工作,并且存在错误的空间,因此它必须值得付出努力。

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


0
投票

这两个限制(函数内部定义的类和类成员函数都不能是模板)的目的是为了简化编译器实现并避免担心与名称解析和代码生成相关的许多边缘情况。例如,模板函数和方法的代码生成已经被推迟,并且其中定义的嵌套模板的代码生成需要进一步推迟。

有一些可用的解决方法:

  • 对于独立功能,移动所需的模板类(和/或 具有模板方法的必需类)到匿名名称空间中 在该函数的定义之前。如果模板类引用 该函数中定义的其他类型或类,将它们移动到 也是匿名命名空间。

  • 对于类方法,匿名命名空间的技巧可能不起作用, 特别是,如果方法内本地声明的模板类需要 访问私有类成员。如果可能的话,将该本地类声明为 另一位私人班级成员代替。

  • 最后,从 C++14 开始,lambda 可以具有

    auto
    参数和
    auto
    返回类型。在许多情况下,您也许能够移动所需的 从本地类到 lambda 的模板功能,特别是如果它 仅本地类的方法需要。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.