结合两个复制和移动的构造函数

fre*_*low 7 c++ templates move-semantics perfect-forwarding c++11

目前,我的一个玩具类模板有两个看起来非常相似的构造函数:

optional(const T& x)
{
    construct(x);
}

optional(T&& x)
{
    construct(std::move(x));
}
Run Code Online (Sandbox Code Playgroud)

我可以将它们组合成一个构造函数模板,还是会以某种方式改变语义?

template<typename U>
optional(U&& x)
{
    construct(std::forward<U>(x));
}
Run Code Online (Sandbox Code Playgroud)

Che*_*Alf 5

抱歉,模板化构造函数永远不会(编译器认为是)复制构造函数。


How*_*ant 2

std::is_constructible它改变了诸如和 等特征std::is_convertible与 交互的方式optional。例如给出:

class A {};

int main()
{
    std::cout << std::is_constructible<optional<A>, int>::value << '\n';
};
Run Code Online (Sandbox Code Playgroud)

您的原始代码将打印出来:

0
Run Code Online (Sandbox Code Playgroud)

但是你的新代码将打印出来:

1
Run Code Online (Sandbox Code Playgroud)

如果这是不可取的,并且您仍然想使用新代码,则可以将enable_if其限制U为可接受的类型。

我看到的唯一可能的问题是是否T可以是引用类型(例如int&)。在这种情况下,原始代码的第二个构造函数看起来很可疑,因为它将传入右值,并且您可能会尝试将该右值绑定到非常量左值引用(无法确定)。如果T永远不能成为引用类型,则无需担心这一点。