本地类中的成员模板
给出以下代码:
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() {}
};
}
我会收到“错误:模板声明不能出现在块作用域”。
Given the following code:
void f()
{
class A
{
template <typename T>
void g() {}
};
}
g++ 4.4 (and also g++-4.6 -std=gnu++0x
) complains: "invalid declaration of member template in local class".
Apparently local classes are not allowed to have template members. What is the purpose of this limitation? Will it be removed in C++0x?
Note: If I make the local class itself a template, rather than giving it a template member:
void f()
{
template <typename T>
class A
{
void g() {}
};
}
I get "error: a template declaration cannot appear at block scope".
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这个限制的目的是什么?只是猜测,但是:
有趣的事实:尝试使用函数中的本地类作为函数中声明的 (c++0x)-lambda 函数的返回类型:MSVC 2010:内部编译器错误 ^^。
The purpose of this limitation? Just a guess, but:
Fun Fact: Try to use a local class within a function as a return type for a (c++0x)-lambda function declared in the function: MSVC 2010: internal compiler error ^^.
这两个限制(函数内部定义的类和类成员函数都不能是模板)的目的是为了简化编译器实现并避免担心与名称解析和代码生成相关的许多边缘情况。例如,模板函数和方法的代码生成已经被推迟,并且其中定义的嵌套模板的代码生成需要进一步推迟。
有一些可用的解决方法:
对于独立函数,移动所需的模板类(和/或
具有模板方法的必需类)到匿名命名空间中
在该函数的定义之前。如果模板类引用
该函数中定义的其他类型或类,将它们移动到
匿名命名空间也是如此。
对于类方法,匿名命名空间的技巧可能不起作用,
特别是,如果方法内本地声明的模板类需要
访问私有类成员。如果可能的话,将该本地类声明为
而是另一个私有类成员。
最后,从 C++14 开始,lambda 可以具有
auto
参数和auto
返回类型。在许多情况下,您也许能够移动所需的
从本地类到 lambda 的模板功能,特别是如果它
仅本地类的方法需要。
The purpose of both limitations (neither classes nor class member functions defined inside of a function may be templates) is to ease compiler implementation and avoid worries about a number of edge cases related to name resolution and code generation. For example, code generation for template functions and methods is already deferred, and the code generation for nested templates defined inside them would need to be deferred further.
There are a few workarounds available:
For standalone functions, move the required template class (and/or
required class with template methods) into an anonymous namespace just
before that function's definition. If the template class references
other types or classes defined in that function, move them to the
anonymous namespace, too.
For class methods, the trick with the anonymous namespace might not work,
especially, if the template class declared locally inside the method needs
access to private class members. If possible, declare that local class as
another private class member instead.
Finally, since C++14, lambdas can have
auto
parameters andauto
return types. In many situations, you may be able to move the required
template functionality from a local class to a lambda, especially, if it
is only required for a method of a local class.