首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何成为模板类的构造函数?

如何成为模板类的构造函数?
EN

Stack Overflow用户
提问于 2010-05-12 23:25:53
回答 4查看 1.7K关注 0票数 6

为什么

代码语言:javascript
复制
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’中声明的成员函数

当完全删除模板时

代码语言:javascript
复制
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()是无效语法?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-05-13 01:52:43

根据对CWG缺陷147的解析(该解析被合并到C++03中),命名类模板专门化的非模板构造函数的正确方法是:

代码语言:javascript
复制
B<int>::B();

而不是

代码语言:javascript
复制
B<int>::B<int>();

如果允许使用后者,那么当类模板专门化的构造函数模板专门化时,就会出现模糊性:第二个<int>是用于类模板还是构造器模板?(有关这方面的更多信息,请参见上文链接的缺陷报告)

因此,将类模板专门化的构造函数声明为朋友的正确方法是:

代码语言:javascript
复制
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接受了正确的形式。在对这个问题的评论中证实了这一点。

票数 5
EN

Stack Overflow用户

发布于 2010-05-13 02:06:50

在后一种情况下,IDE将朋友B::B()显示为无效语法的原因是什么?IDE错误。

如果不能升级,我在gcc中找到了一个解决办法,就是将B()的实现移动到一个成员函数void::init(),并与之建立友谊。我敢打赌这也关闭了你的IDE。

但是,即使您要编译它,只要尝试实例化B,就会遇到堆栈溢出问题。

票数 1
EN

Stack Overflow用户

发布于 2010-05-13 02:08:44

一个类型的人不起作用吗?例如:

代码语言:javascript
复制
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段排除了嵌套的名称说明符friendusing。如果它确实适用于朋友声明,它似乎也禁止friend Base::B();

使用可选的函数说明符序列(7.1.2)、构造函数的类名和参数列表,使用特殊的声明器语法来声明或定义构造函数。

那些函数说明符是inlinevirtualexplicit和构造函数,无论如何都不能是virtual

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2823485

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档