【问题标题】:template copy constructor模板复制构造函数
【发布时间】:2012-09-12 00:56:58
【问题描述】:

鉴于以下代码,Foo 是否具有复制构造函数?将 Foo 与 STL 容器一起使用是否安全?

class Foo
{
public:
   Foo() {}

   template <typename T>
   Foo(const T&) {}   
};

【问题讨论】:

    标签: c++


    【解决方案1】:

    该标准明确指出,复制构造函数是一个非模板构造函数,它接受对同一类型的可能 const-volatile 对象的引用。在上面的代码中,您有一个 conversion 但没有 copy 构造函数(即它将用于所有 but 副本,其中隐式声明的构造函数将使用)。

    Foo 有复制构造函数吗?

    是的,隐式声明/定义的复制构造函数。

    Foo 与标准库容器一起使用是否安全?

    使用Foo 的当前定义,但在一般情况下,这取决于Foo 具有哪些成员以及隐式定义的复制构造函数是否正确管理这些成员。

    【讨论】:

    • 如果在模板Foo(const Foo&amp;) = delete;之前声明会发生什么?该类现在是否没有复制构造函数或模板被调用了?
    • 如果复制构造函数被删除,那么类就没有了。 ;-)
    • @nightcracker 然后没有复制构造函数并且编译器给出一个错误(除非你有一个表达式,例如可以使用移动复制构造函数)。关键是拷贝构造函数是non-templated.
    • 在哪里中使用了隐式复制构造函数?似乎只有当这种类型用作具有默认复制构造函数的较大类型的子对象时。
    • @BenVoigt:我不确定我是否理解评论。在代码中没有使用它,但问题是关于能够在容器中使用这种类型(关注复制构造函数)。也许我应该更清楚一点,隐式声明的复制构造函数仅在 used 时才定义?这是你的担心吗?每当复制这种类型的对象时,都会定义复制构造函数,它不必是更大对象的一部分(例如:Foo f, g(f);
    【解决方案2】:

    根据标准,复制构造函数必须是以下签名之一:

    Foo(Foo &);
    Foo(Foo const &);
    Foo(Foo volatile &);
    Foo(Foo const volatile &);
    
    Foo(Foo&, int = 0, );
    Foo(Foo&, int = 0, float = 1.0); //i.e the rest (after first) of the 
                                     //parameter(s) must have default values!
    

    由于您代码中的模板构造函数与上述任何一种形式都不匹配,即不是 copy-constructor。

    【讨论】:

    • 也可以有默认参数
    • @NikitaTrophimov:是的,也是。
    【解决方案3】:

    Foo有一个编译器生成的拷贝构造函数,不能用你提供的模板转换构造函数代替。

    Foo f0;
    Foo f1(f0); // calls compiler-synthesized copy constructor
    Foo f2(42); // calls template conversion constructor with T=int
    

    【讨论】:

    猜你喜欢
    • 2011-05-24
    • 2016-09-12
    • 2016-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-14
    • 1970-01-01
    • 2015-12-08
    相关资源
    最近更新 更多