目前,我的玩具类模板之一有两个看起来非常相似的构造函数:
optional(const T& x)
{
construct(x);
}
optional(T&& x)
{
construct(std::move(x));
}
我可以将它们组合成一个构造函数模板,还是会以某种方式改变语义?
template<typename U>
optional(U&& x)
{
construct(std::forward<U>(x));
}
目前,我的玩具类模板之一有两个看起来非常相似的构造函数:
optional(const T& x)
{
construct(x);
}
optional(T&& x)
{
construct(std::move(x));
}
我可以将它们组合成一个构造函数模板,还是会以某种方式改变语义?
template<typename U>
optional(U&& x)
{
construct(std::forward<U>(x));
}
模板化的构造函数永远不会(编译器认为是)复制构造函数,抱歉。
It changes the way traits such as std::is_constructible
and std::is_convertible
interact with optional
. For example given:
class A {};
int main()
{
std::cout << std::is_constructible<optional<A>, int>::value << '\n';
};
Your original code would print out:
0
But your new code will print out:
1
If this is undesirable, and you still want to go with your new code, you could enable_if
it to restrict U
to acceptable types.
The only other possible issue I see is if T
can be a reference type (e.g. int&
). In that case the second constructor of your original code looks suspicious as it would be passing in an rvalue, and you might be trying to bind that rvalue to a non-const lvalue reference (can't tell for sure). If T
can never be a reference type, no need to worry about this.
哦,construct 不是构造函数,它是成员函数模板。
那么可能语义不同。您的原始重载集将左值引用传递给 const 或将右值引用传递给非 const。模板版本也可以将左值引用传递给非常量。(我忽略了对 const 的右值引用。)
尽管construct
很可能被声明为接受U&&
(否则您之前移动 a 的重载T
将不起作用)并且在这种情况下应该处理非常量左值,或者被声明为接受U const&
并且在这种情况下它是无害的。
假设您至少construct(const T& x)
并且可能添加了construct(T&& x)
定义,并且您的 type 对象U
可以转换为 type 对象T
,我认为您应该没问题...
U
将绑定到construct(const T& x)
U
将绑定到construct(const T& x)
U
将绑定到construct(T&& x)
或construct(const T& x)
未定义 r-value 引用版本U
will bind to construct(const T& x)