使Friend成为模板类的构造函数
Make Friend the constructor of a template class
最近我开始使用模板。我只是转储了一个编译错误。
我有一个类模板Foo
,它采用布尔B
作为模板参数。我试着交一个朋友,在带有模板参数b
的Foo
的实例化中,带有参数!b
的Foo的另一个实例化的构造函数,代码是:
template<bool B>
class Foo
{
public:
Foo(Foo<!B>&);
private:
friend Foo<!B>::Foo(Foo<B>&);
};
编译器返回以下错误:
test.cpp:22:18: error: C++ requires a type specifier for all declarations
friend Foo<!B>::Foo(Foo<B>&);
~~~~~~ ^
test.cpp:22:18: error: constructor cannot have a return type
friend Foo<!B>::Foo(Foo<B>&);
^~~
2 errors generated.
我用以下命令编译了它:在Windows上使用clang++ -std=c++11 foo.cpp
。
我真的不知道如何让它发挥作用,任何帮助我理解错误的地方都是值得感激的。
我在评论别人的回答,他们让我把我的分析粘贴到这里。
我认为您的情况有问题,因为Foo<true>
对Foo<false>
的成员函数有一个友元声明,而该友元声明又引用了Foo<true>
的成员函数。虽然成员分别在成员函数之前声明,但编译器不支持这种循环引用。GCC在实例化时抱怨
main.cpp: In instantiation of 'class Foo<false>':
main.cpp:9:12: required from 'class Foo<true>'
main.cpp:15:49: required from here
main.cpp:9:12: error: invalid use of incomplete type 'class Foo<true>'
friend Foo<!B>::Foo(Foo<B>&);
这个错误消息有点令人困惑,因为它表明不完整的类型不能与::
一起使用,这是错误的。正在定义的类可以与::
一起使用,即使它还不完整。然而,GCC对正在实例化的类的处理与正在定义的类不同,并且GCC显然不支持以限定名称引用回正在实例化的类别。
我们有一个关于这种循环引用的DR,http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#287这似乎使其合法,但正如最后声明所指出的,"这需要工作",所以GCC有权拒绝您的代码。更令人困惑的是,我们还有一个关于友元函数声明中使用的名称的显式规则,DR287中没有提到它,它的"好像"会使代码格式错误,因为Foo<!B>
的实例化点就在Foo<B>
的实例化点之前,除非我们在DR287中应用该规则,否则无法看到Foo<B>
的构造函数声明。
友元类或函数可以在类模板中声明。当一个模板被实例化时,它的朋友的名字被视为在其实例化时明确声明了专门化
与此无关,还有另一个问题:Foo<!B>::Foo(Foo<B>&);
是指构造函数吗?如果它引用了注入的类名,那么它就是对构造函数的引用,编译器必须将其视为这些constext中的构造函数。因此编译器必须解析Foo<!B>::Foo
。但Foo<!B>
是一个依赖类型,因此编译器无法查看它来决定它是什么类型的名称(请记住,struct A { int A; }
是允许的,编译器必须验证它不处于这种情况(。我认为由于这些原因,cland无法解析您的模板,因为它对friend Foo<!B>::Foo(Foo<B>&)
的含义感到困惑。
我相信模板本身(忽略实例化问题(应该是良好的形式,因为编译器可能会延迟Foo<!B>::Foo
的查找,并将其视为实际的非类型(构造函数(。
- "error: no matching function for call to"构造函数错误
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 选择要调用的构造函数
- 如何委托派生类使用其父构造函数?
- 构造函数正在调用一个使用当前类类型的函数
- 没有用于初始化C++中的变量模板的匹配构造函数
- 初始化具有非默认构造函数的std::数组项的更好方法
- 当从函数参数中的临时值调用复制构造函数时
- 在c++构造函数中使用随机字符串生成器
- 一对向量构造函数:初始值设定项列表与显式构造
- 从构造函数抛出异常时如何克服内存泄漏
- 我不明白为什么我声明一个空的内部结构并将其传递给构造函数
- 继承:构造函数,初始化C++11中基类的类C数组成员
- 具有默认模板类型的默认构造函数的类型推导
- 无法访问Friend类的私有构造函数
- C++Friend构造函数
- 使Friend成为模板类的构造函数