【问题标题】:bool class template generic copy and move constructorbool 类模板通用复制和移动构造函数
【发布时间】:2020-11-16 09:15:15
【问题描述】:

我试图为一个类模板实现一个复制构造函数,它允许所有实例化从一个版本的类模板转换为另一个版本。

这导致以下代码

#include <memory>
#include <iostream>

template<bool binary>
class Bar {
private:
    friend class Bar<!binary>;
    std::unique_ptr<int> data;
public:
    Bar(int example) : data(std::make_unique<int>(example)) {

    }

    template<bool value>
    Bar(const Bar<value>& bar) : data(std::make_unique<int>(*bar.data)) {

    }

    //other methods that differ depending on binary value...
};

int main() {
    Bar<false> b1{ 1 };
    Bar<false> b2{ b1 }; //causes compile error
    Bar<true> b3{ b1 }; //works as expected
}

从不同类型构造可以工作,但从相同类型构造会发出编译时错误提示

Bar::Bar(const Bar &)': 试图引用一个 删除功能

显然没有调用通用复制构造函数,这导致我手动写出复制构造函数,导致当前代码。

#include <memory>
#include <iostream>

template<bool binary>
class Bar {
private:
    friend class Bar<!binary>;
    std::unique_ptr<int> data;
public:
    Bar(int example) : data(std::make_unique<int>(example)) {

    }

    Bar(const Bar& bar) : data(std::make_unique<int>(*bar.data)) {

    }

    template<bool value>
    Bar(const Bar<value>& bar) : data(std::make_unique<int>(*bar.data)) {

    }

    //other methods that differ depending on binary value...
};

int main() {
    //all work as expected.
    Bar<false> b1{ 1 };
    Bar<false> b2{ b1 };
    Bar<true> b3{ b1 };
    Bar<true> b4{ b3 }; 
}

值得注意的是,这对于移动构造函数、复制赋值运算符和移动赋值运算符也是必需的。 因此,我有两个问题

  1. 为什么通用复制或移动构造函数不会覆盖复制/移动构造函数?
  2. 是否有更好的解决方法来允许相同类型和替代类型的复制构造?截至目前,我基本上必须为每个复制/移动构造函数和赋值运算符复制代码。

【问题讨论】:

    标签: c++ templates copy-constructor unique-ptr


    【解决方案1】:

    来自https://en.cppreference.com/w/cpp/language/copy_constructor

    类 T 的复制构造函数是一个非模板构造函数,其 第一个参数是 T&‍, const T&‍, volatile T&‍, 或 const volatile T&‍,或者没有其他参数,或者剩下的 参数都有默认值。

    因此,您不能以这种方式为复制 ctor 定义新参数。

    现在,如果您使用Bar&lt;false&gt;(const Bar&lt;true&gt;&amp;)Bar&lt;false&gt;(const Bar&lt;true&gt;&amp;),编译器将使用在实例化类时生成的普通cpy ctor,并且不会实例化您相应的模板化ctor。

    如果这是真的,让编译器来定义复制ctor,但将unique_ptr更改为shared_ptr(因为unique_ptr作为成员var,该类是不可复制的),或者定义两个像你在第二个代码中的那样。

    下面的代码,我用shared_ptr,没有出现错误

    但请注意,模板化的 cpy ctor 在为 Bar&lt;true/false&gt;(const Bar&lt;false/false&gt;&amp;) 执行时不会为 Bar&lt;false/true&gt;(const Bar&lt;false/true&gt;&amp;) 执行

    #include <memory>
    #include <iostream>
    
    template<bool binary>
    class Bar {
    private:
        Bar& operator=(const Bar&) = delete ;
        friend class Bar<!binary>;
        std::shared_ptr<int> data;
    public:
    
        template<bool value>
        Bar(const Bar<value>& bar) : data(std::make_shared<int>(*bar.data)) {
            std::cout << __PRETTY_FUNCTION__ <<"\n";
    
        }
        Bar(int example) : data(std::make_shared<int>(example)) {
    
        }
    
        //other methods that differ depending on binary value...
    };
    
    int main() {
        Bar<false> b1{ 1 };
        Bar<false> b2{ b1 };
        Bar<true> b3 {b1};
        Bar<true> b4 {b3};
        Bar<false> b5 {b4};
    
    }
    

    Live

    【讨论】:

      猜你喜欢
      • 2019-08-11
      • 2022-01-12
      • 1970-01-01
      • 2016-03-22
      • 2016-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-02
      相关资源
      最近更新 更多