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 };
}
值得注意的是,这对于移动构造函数、复制赋值运算符和移动赋值运算符也是必需的。
因此,我有两个问题
- 为什么通用复制或移动构造函数没有掩盖 copy/move 构造函数?
- 是否有更好的解决方法来允许相同类型和替代类型的复制构造?截至目前,我基本上必须为每个 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};
}
我试图为 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 };
}
值得注意的是,这对于移动构造函数、复制赋值运算符和移动赋值运算符也是必需的。 因此,我有两个问题
- 为什么通用复制或移动构造函数没有掩盖 copy/move 构造函数?
- 是否有更好的解决方法来允许相同类型和替代类型的复制构造?截至目前,我基本上必须为每个 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};
}