加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

templates – 指定了多个复制构造函数

发布时间:2020-12-16 06:57:49 所属栏目:百科 来源:网络整理
导读:使用Visual C 2010,我有一个这样的类: class MyClass{public: MyClass(){} MyClass(MyClass ){/*...*/} //A MyClass(const MyClass ){/*...*/} //B templatetypename T MyClass(T t){ static_assert( !std::is_sametypename std::remove_cvtypename std::re
使用Visual C 2010,我有一个这样的类:

class MyClass{
public:
    MyClass(){}
    MyClass(MyClass &){/*...*/}   //A
    MyClass(const MyClass &){/*...*/}   //B
    template<typename T> MyClass(T &&t){ static_assert(
        !std::is_same<typename 
        std::remove_cv<typename  std::remove_reference<T>::type>::type,MyClass>::value,"Wrapping over wrapping is not allowed!"); } //C
};

int main(int,char**){
    MyClass a;
    const MyClass b(a); //assert fail if line A removed
    auto c=b; //assert fail if line B removed
}
//If both A and B exists
//Warning C4521: multiple copy constructors specified
//Furthermore,if both A and B removed
//No error or warnings; VC2010 accepts peacefully.
//In debug mode you will find the compiler generated trivial copy constructor

根据C标准,A行和B行都被认为是复制构造函数,C是转换构造函数.我收到警告,我宣布多个拷贝构造函数,这并不奇怪.但是,如果我删除它们中的任何一个,static_assert失败并且代码将无法编译,这意味着模板构造函数接收到控件.

我确信这种行为遵循函数重载的规则.然而,这是两个规则的冲突吗?如果A和B是复制构造函数并且其中一个被声明,那么复制对象的任何尝试都不应该放到模板中,是不是?

更新:
根据N3242,12.8.7,

“a member function template is NEVER INSTANTIATED to perform the copy of a class object to an object of its class type.”

正确的实施应该是:

>当A或B或两者都被删除时,不应发生断言失败.
>如果删除了行B,则c的构造应该失败,因为b是const.
>如果两行都被删除,编译器应该为该类生成一个拷贝构造函数.
>如果两条线都存在,则由实施来警告用户.

任何意见?

解决方法

首先,模板< T>应该是模板< typename T>.

我在64位Ubuntu Linux上使用gcc 4.4.3,代码的行为与你在帖子中演示的不同.

>如果没有任何改变,代码可以在没有任何警告的情况下编译.构造函数A和B一个接一个地被唤起.>如果我对A行进行评论,则无法像你所说的那样进行编译:在行const MyClass b(a);中失败.原因是对象a不是常量,因此构造函数B不能匹配,编译器必须实例化模板构造函数.当然,const MyClass和MyClass是不同的类型.>但是,如果我只对B行进行注释,则可以成功编译代码并激活模板复制构造函数.对象b是一个常量对象,因此构造A不能匹配,编译器实例化模板构造函数.但问题仍然存在:static_assert是否会失败?差异可能是由于平台/编译器的差异. GCC似乎将is_same< MyClass&&,MyClass> ::值实现为true.您可以使用typeid打印出两种类型.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读