gpt4 book ai didi

c++ - 作为左值引用或右值拷贝的数据成员

转载 作者:行者123 更新时间:2023-11-27 23:13:44 25 4
gpt4 key购买 nike

考虑以下结构模板:

template<typename T>
struct X
{
X(T t) : t(std::forward<T>(t)) {}

T t;
};

其中 T 将是左值引用(例如,const int&)或常规值(例如,int)。这个想法是在 Xlvalue 构造时使用左值引用,而在由 rvalue 构造时使用常规值。

因此,定义了以下工厂函数来创建具有此类属性的 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,每个类都需要四个工厂函数。

最佳答案

this results in non-const lvalue-references when constructed from lvalues, and I would like them to be const lvalue-references

您可以编写一个简单的特征来转换左值引用:

template<class T>
struct transform_parameter{ using type = T; };

template<class T>
struct transform_parameter<T&>{ using type = T const&; };

template<class T>
using TransformParameter = typename transform_parameter<T>::type;

并将其应用于所有相关模板参数:

template<class T>
X<TransformParameter<T>> make_X(T&& v){
return {std::forward<T>(v)};
}

我在这里还使用了一个 braced-init-list(又名统一初始化)来避免我写两次类型。

关于c++ - 作为左值引用或右值拷贝的数据成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18126918/

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