gpt4 book ai didi

c++ - 为什么模板化非 const 参数构造函数优于给定的复制构造函数

转载 作者:搜寻专家 更新时间:2023-10-31 01:28:31 24 4
gpt4 key购买 nike

我想让我的类能够在 std::variant 中使用。

应该工作的简单代码是:

int main()
{
std::variant< int, A > v;

A a(1);
v = a;
}

我的类包含一个模板化的构造函数:

 template <typename T> A( T& );

此时麻烦开始了!构造函数绑定(bind)到来自 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&< 的复制构造函数---这通常不是预期的行为。为了防止这种情况,我们通常使用 SFINAE 来约束这个构造函数:

template <typename T, typename = std::enable_if_t<!std::is_same_v<std::decay_t<T>, A>>>
A(T& t) // or T&& t

并可能考虑将其设为显式

我们通常不提供采用非 const A& 的复制构造函数,因为它们在采用 const A& 的那些旁边是多余的。

关于c++ - 为什么模板化非 const 参数构造函数优于给定的复制构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52021074/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com