我正在尝试对 std::tuple
进行转换初始化(称为 w
),其中包含另一个 std::tuple
中的元素(称为 t
)具有相同的大小但不同的元素类型。
在我的应用程序中,w
的元素必须使用 non-const reference
构造到 t
的相应元素.
不幸的是,只存在 4) converting copy-ctor
和一个 5) converting move-ctor
对于 std::tuple
(reference)。这意味着,来自 w
的新元素只能使用 const reference
进行初始化或rvalue reference
到 t
的元素,两者都不适用。
示例
首先我们有一个元素修饰符类,它仅绑定(bind)到其元素类型的引用。
template<typename T>
struct SingleElementModifier {
T& ref;
SingleElementModifier(T& ref) : ref(ref) { }
};
接下来是一个类型特征来获取 w
的类型给定 t
的类型。本质上它包装了 t
中的每个元素。进入SingleElementModifier
.
template<typename T> struct ModifierTuple;
template<typename... Ts>
struct ModifierTuple<std::tuple<Ts...>> {
using Type = std::tuple<SingleElementModifier<Ts>...>;
};
现在我们有一个TupleModifier
需要一个元组 t
并存储一个元组 w
第一个元组的每个元素都有修饰符。
template<typename Tuple>
struct TupleModifier {
using TupleType = typename ModifierTuple<Tuple>::Type;
TupleType w;
TupleModifier(Tuple& t) : w{ t } { }
};
现在我们只需要选择一些元组 t
并创建修饰符。
int main() {
/* just some example types, could be any type inside. */
std::tuple<double, std::pair<int, int>> t;
TupleModifier mod(t);
}
<强> Live example
这里编译器将停止并向我提示没有 w{ t }
的构造函数可以找到,原因在开头已经解释过了。
糟糕的解决方法
理论上,我可以 SingleElementModifier
拍个const T&
并使用const_cast
摆脱 const,但我希望有一个更好的解决方案,不需要我放弃 const 正确性。
最佳答案
你只需要一点间接:
template<typename Tuple>
struct TupleModifier {
using TupleType = typename ModifierTuple<Tuple>::Type;
TupleType w;
TupleModifier(Tuple& t)
: TupleModifier{ t, std::make_index_sequence<std::tuple_size<Tuple>::value>() }
{}
private:
template <std::size_t ... Is>
TupleModifier(Tuple& t, std::index_sequence<Is...>) : w{ std::get<Is>(t)...} { }
};
关于c++ - 使用对另一个不同类型的元组元素的非常量引用来初始化元组的元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48994215/