【问题标题】:Initializing a tuple's elements with non-const references to another tuple's elements of different type使用对另一个元组的不同类型元素的非常量引用来初始化元组的元素
【发布时间】:2018-02-26 17:47:54
【问题描述】:

我正在尝试使用来自另一个 std::tuple(称为 t)的具有相同大小但不同元素类型的元素对 std::tuple(称为 w)进行转换初始化。

在我的应用程序中,w 的元素必须使用non-const referencet 的相应元素来构造。

不幸的是,std::tuple (reference) 只存在一个4) converting copy-ctor 和一个5) converting move-ctor。这意味着,来自w 的新元素只能使用const referencervalue reference 初始化为t 的元素,两者都不适用。

示例

首先我们有一个元素修饰符类,它只绑定到其元素类型的引用。

template<typename T>
struct SingleElementModifier {
    T& ref;
    SingleElementModifier(T& ref) : ref(ref) { }
};

在给定t 的类型的情况下,接下来一个类型特征来获取w 的类型。本质上,它将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&amp; 并使用const_cast 来摆脱 const,但我希望有一个更好的解决方案,不需要我抛弃 const 正确性。

【问题讨论】:

    标签: c++ c++11 templates c++17


    【解决方案1】:

    你只需要一点间接性:

    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)...} { }
    };
    

    Demo

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-09
      • 2012-09-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-21
      • 1970-01-01
      相关资源
      最近更新 更多