我看到了以下预C++11代码,用作声明类模板朋友的技巧(在C++11中可以简单地用friend T;完成)
template <typename T>
struct Wrapper
{
typedef T type;
};
template <typename T>
class Foo
{
friend class Wrapper<T>::type; // effectively makes T a friend
};
struct Test{};
int main()
{
Foo<Test> foo;
}该代码在g++上编译得很好(4.9/5.1/6),但是在clang++ (3.5/3.6/3.7)下出现了错误。
错误:精化类型指类型为 好友类包装::类型;
以上代码是否符合标准,即是否有效?
发布于 2015-05-21 19:04:26
§7.1.6.3/2:
如果标识符解析为一个elaborated-type-specifier -name,或者简单模板id解析为别名模板专门化,则是格式错误的。
发布于 2015-05-21 19:02:41
这不符合规定。rules . friend /3中的语法规则是:
不声明函数的朋友声明应具有下列形式之一:朋友详细说明型说明符;朋友简单类型说明符;朋友类型说明符;
class Wrapper<T>::type不是这些说明符类型。它不是一个详细的类型说明符,因为Wrapper<T>::type不是标识符或类名,显然也不是另外两种类型的名称之一。你要找的只是:
friend typename Wrapper<T>::type;发布于 2015-05-21 19:03:15
Dcl.tydurif/p8:
注意:一个名为类类型或cv限定版本的类型胡枝子名称也是一个类名(9.1),如果使用一个elaborated-type-specifier (7.1.6.3)、类定义(第9条)、构造函数声明(12.1)或析构函数声明(12.4),则程序是错误的。-尾注
代码应该在模板实例化时间失败,这在Clang中是正确的。
使用typename代替struct允许代码在两个编译器中传递。
https://stackoverflow.com/questions/30381690
复制相似问题