为什么
class A;
template<typename T> class B
{
private: 
    A* a;
public:  
    B();
};
class A : public B<int>
{
private:    
    friend B<int>::B<int>();
    int x;
};
template<typename T>
B<T>::B()
{
    a = new A;
    a->x = 5;
}
int main() { return 0; }结果
../src/main.cpp:15:错误:无效使用构造函数作为模板 ../src/main.cpp:15:注意:用‘B::B’代替‘B::类B’命名构造函数
但是,将friend B<int>::B<int>()更改为friend B<int>::B()将导致
../src/main.cpp:15: error: no‘void::B()’在类‘B’中声明的成员函数
当完全删除模板时
class A;
class B
{
private:
    A* a;
public:
    B();
};
class A : public B
{
private:
    friend B::B();
    int x;
};
B::B()
{
    a = new A;
    a->x = 5;
}
int main() { return 0; }编译和执行都很好--尽管我的IDE说朋友B::B()是无效语法?
发布于 2010-05-13 01:52:43
根据对CWG缺陷147的解析(该解析被合并到C++03中),命名类模板专门化的非模板构造函数的正确方法是:
B<int>::B();而不是
B<int>::B<int>();如果允许使用后者,那么当类模板专门化的构造函数模板专门化时,就会出现模糊性:第二个<int>是用于类模板还是构造器模板?(有关这方面的更多信息,请参见上文链接的缺陷报告)
因此,将类模板专门化的构造函数声明为朋友的正确方法是:
friend B<int>::B();Comeau 4.3.10.1和Intel C++ 11.1都接受这种形式。VisualC++ 2008和Visual C++ 2010都不接受该表单,但都接受(不正确的)表单friend B<int>::B<int>(); (我将在Microsoft上提交缺陷报告)。
gcc在4.5版之前不接受任何一种形式。Bug 5023是针对gcc 3.0.2报告的,但错误报告中所要求的解决方案是无效的。看来错误9050的决议也解决了这个问题,gcc 4.5接受了正确的形式。在对这个问题的评论中证实了这一点。
发布于 2010-05-13 02:06:50
在后一种情况下,IDE将朋友B::B()显示为无效语法的原因是什么?IDE错误。
如果不能升级,我在gcc中找到了一个解决办法,就是将B()的实现移动到一个成员函数void::init(),并与之建立友谊。我敢打赌这也关闭了你的IDE。
但是,即使您要编译它,只要尝试实例化B,就会遇到堆栈溢出问题。
发布于 2010-05-13 02:08:44
一个类型的人不起作用吗?例如:
class A : public B<int>
{
    typedef B<int> Base;   
    friend Base::Base();
    int x;
};编辑: C++0x的最后委员会草案包括3.4.3.1节class.qual中的以下语言
在查询中,构造函数是可接受的查找结果,嵌套名称说明符指定了类C:如果在嵌套名称说明符后面指定的名称(在C中查找时)是C的注入类名(第9条),或者嵌套名称说明符后面指定的名称与嵌套名称说明符的最后一个组件中的标识符或简单模板id的模板名称相同,则该名称被考虑命名为C的构造函数。
听起来,嵌套名称说明符(Base)后面指定的名称(Base::)与嵌套名称说明符的最后一个组件中的标识符相同,因此这段代码确实命名了一个构造函数。
但我无法与12.1节class.ctor相一致
因为构造函数没有名称,所以在查找名称时找不到它们。
哦真的?3.4.3.1中的这种语言又起作用了吗?
在构造函数声明的声明符-id中,不能使用typedef名称作为类名。
这似乎很清楚,但第12.1节似乎只讨论了引入构造函数的声明,因为第1段排除了嵌套的名称说明符friend和using。如果它确实适用于朋友声明,它似乎也禁止friend Base::B();。
使用可选的函数说明符序列(7.1.2)、构造函数的类名和参数列表,使用特殊的声明器语法来声明或定义构造函数。
那些函数说明符是inline、virtual、explicit和构造函数,无论如何都不能是virtual。
https://stackoverflow.com/questions/2823485
复制相似问题