考虑以下结构模板:
template<typename T>
struct X
{
X(T t) : t(std::forward<T>(t)) {}
T t;
};
其中 T 将是左值引用(例如const int&
)或常规值(例如int
)。这个想法是在从左值X
构造时使用左值引用,在从右值构造时使用常规值。
因此,定义了以下工厂函数来创建X
具有此类属性的实例:
template<typename T>
X<const T&>
CreateX(const T& val)
{
return X<const T&>(val);
}
template<typename T>
typename std::enable_if<std::is_rvalue_reference<T&&>::value, X<T>>::type
CreateX(T&& val)
{
return X<T>(std::move(val));
}
到现在为止还挺好。如果我们现在考虑结构模板Y
:
template<typename T, typename U>
struct Y
{
Y(T t, U u) : t(std::forward<T>(t)), u(std::forward<T>(u)) {}
T t;
U u;
};
我们决定和之前做同样的类比X
,我们最终得到了这四个工厂函数:
template<typename T, typename U>
Y<const T&, const U&>
CreateY(const T& t, const U& u)
{
return Y<const T&, const T&>(t, u);
}
template<typename T, typename U>
typename std::enable_if<std::is_rvalue_reference<T&&>::value, Y<T, const U&>>::type
CreateY(T&& t, const U& u)
{
return Y<T, const U&>(std::forward<T>(t), u);
}
template<typename T, typename U>
typename std::enable_if<std::is_rvalue_reference<U&&>::value, Y<const T&, U>>::type
CreateY(const T& t, U&& u)
{
return Y<const T&, U>(t, std::forward<T>(u));
}
template<typename T, typename U>
typename std::enable_if<std::is_rvalue_reference<T&&>::value and std::is_rvalue_reference<U&&>::value, Y<T, U>>::type
CreateY(T&& t, U&& u)
{
return Y<T, U>(std::forward<T>(t), std::forward<T>(u));
}
是否有另一种方法可以获得相同的结果,也许不那么冗长?幸运的是,我的应用程序需要的模板数据成员不超过两个,但需要其他几个类似的类Y
,每个类都需要四个工厂函数。