[英]why templated non const parameter constructor is preferred to given copy constructor
我想讓我的課程可以在std::variant
。
應該起作用的簡單代碼是:
int main()
{
std::variant< int, A > v;
A a(1);
v = a;
}
我的課程包含一個模板化的構造函數:
template <typename T> A( T& );
此時麻煩開始了! 構造函數綁定到來自std::variant
的調用,不再使用提供的A(const A&)
。
由於復制和粘貼的原因,此處的完整示例為:
#include <iostream>
#include <variant>
class A
{
private:
int x;
public:
A( A&&) {}
A( const A& ) {}
A(){}
~A() {}
A& operator=( const A& ) { return *this;}
A& operator=( A&& ) {return *this;}
template <typename T>
A( T& t )
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
A(int _x):x{_x}{}
};
int main()
{
std::variant< int, A > v;
A a(1);
v = a;
}
背景:
為什么在這里使用模板? 使用使用序列化程序類型的構造函數時,問題開始。 序列化器可以有多種類型,取決於要序列化的文件或流。
備注:我知道構造函數的功能缺失!
問題不在於std::variant
。 問題在於構造器模板,
template <typename T>
A(T& t)
這樣的構造函數是有問題的,因為當參數是類型A
的非const
左值時,此構造函數優於采用const A&
-的副本構造const A&
這通常不是預期的行為。 為了防止這種情況,我們通常用SFINAE約束此構造函數:
template <typename T, typename = std::enable_if_t<!std::is_same_v<std::decay_t<T>, A>>>
A(T& t) // or T&& t
並可能考慮將其explicit
。
我們通常不提供拷貝構造函數以非const
A&
因為它們旁邊多余的那些服用const A&
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.