bool class 模板通用复制和移动构造函数

bool class template generic copy and move constructor

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

这导致以下代码

#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 &)': attempting to reference a deleted function

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

#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. 为什么通用复制或移动构造函数没有掩盖 copy/move 构造函数?
  2. 是否有更好的解决方法来允许相同类型和替代类型的复制构造?截至目前,我基本上必须为每个 copy/move 构造函数和赋值运算符复制代码。

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

A copy constructor of class T is a non-template constructor whose first parameter is T&‍, const T&‍, volatile T&‍, or const volatile T&‍, and either there are no other parameters, or the rest of the parameters all have default values.

因此您不能以这种方式为复制构造函数定义新参数。

现在,如果您使用 Bar<false>(const Bar<true>&)Bar<false>(const Bar<true>&),编译器将使用在实例化 class 时生成的普通 cpy ctor,而不会实例化您相应的模板化ctor.

如果这是真的,让编译器定义复制构造函数,但将 unique_ptr 更改为 shared_ptr(因为 unique_ptr 作为成员 var class 不可复制),或者像第二个代码中那样定义两个 ctors。

对于下面的代码,我使用了shared_ptr并且没有发生错误

但请注意,模板化的 cpy ctor 在执行 Bar<true/false>(const Bar<false/false>&)

时不会执行 Bar<false/true>(const Bar<false/true>&)
#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