我试图为类模板实现一个复制构造函数,该构造函数允许所有实例化从类模板的一个版本转换到另一个版本。
这导致以下代码
#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 };
}
值得注意的是,这对于move构造函数、复制赋值运算符和move赋值运算符也是必要的。因此,我有两个问题
- 为什么泛型复制或移动构造函数不盖过复制/移动构造函数
- 是否有更好的解决方法来允许同时使用相同类型和备用类型的复制构造?到目前为止,我必须为每个复制/移动构造函数和赋值运算符基本上复制代码
来源https://en.cppreference.com/w/cpp/language/copy_constructor
类T的复制构造函数是一个非模板构造函数,其第一个参数是T&,常量T&,挥发性T&,或常量volatileT&,并且要么没有其他参数,要么所有参数都有默认值。
因此,不能以这种方式为复制ctor定义新参数。
现在,如果使用Bar<false>(const Bar<true>&)
或Bar<false>(const Bar<true>&)
,编译器将使用在实例化类时生成的普通cpy-ctor,而不会实例化相应的模板化ctor。
如果这是真的,请让编译器定义复制ctor,但将unique_ptr
更改为shared_ptr
(因为unique_ptr
是成员var,所以该类不可复制(,或者在第二段代码中定义两个ctor。
对于下面的代码,我使用了shared_ptr
,没有出现错误
但请注意,模板化cpy ctor不为Bar<false/true>(const Bar<false/true>&)
执行,而为Bar<true/false>(const Bar<false/false>&)
执行
#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};
}
实时