如何在C ++ 11中将整数序列扩展为下标运算符?

时间:2016-11-08 07:04:57

标签: c++11 variadic-templates

让我们定义输入:

double values[2][2]...[2] N times
bool signs[N];

我想要做的是为这样的事情写一个模板函数:

auto result = values[signs[0]][signs[1]]...[signs[N - 1]];

不幸的是,如果没有折叠C ++ 17的表达式,我无法实现它。

我确定我需要以某种方式使用std::index_sequence<>

template <std::size_t ... indices>
double get_value(const dimension_creator_t<sizeof...(indices)>& values, 
                 index_sequence<indices...>, bool (&signs)[sizeof...(indices)])

但不确定如何继续。我可以在线找到std::integer_sequence的代码。 dimension_creator_tvalues类型的别名。

如何实现所需的功能?

1 个答案:

答案 0 :(得分:3)

以下内容应该有效,但我使用std::array取代了一些自由。它更方便一点。

每次调用value_getter<size,I>::get<T>都需要std::array<T,2>作为参数,并根据signs[I]对其进行修剪,因此我们得到类型为T的arr[signs[I],这也是一个嵌套数组(如果我!= size)所以我们再次以T为参数调用value_getter<size,I>::get

一个帮助器value_getter结构,用于逐个修剪嵌套数组。

template <std::size_t size, std::size_t I> struct value_getter {
template <typename T>
    static double& get(std::array<T,2>& arr, const std::array<bool, size>& signs) {
        return value_getter<size, I+1>::template get(arr[signs[I]], signs);
    }
};

返回对值的引用的最终基本案例。

template <std::size_t size> struct value_getter<size, size> {
    static template <typename T> double& get(T& arr, const std::array<bool, size>& signs) {
        return arr;
    }
};

用法:

 std::array< std::array< std::array< double, 2>, 2>, 2> values{};
 std::array<bool, 3> signs{};

 double v = value_getter<3,0>::template get(values, signs);

Demo

我正在思考如何使其与C数组样式一起使用,问题是如何在std::array<T,2>函数中表示类型::get。它可以通过类似std::add_pointer<T>的内容工作,该T*应该从T提供T

因此,对于C风格的数组来说,它实际上要简单得多。

这里arr表示数组本身。如果我们绕过一些静态错误检查,T基本上不用作类型。由于我们知道T类型的I != size是一个数组(如果operator[]),那么我们始终可以在arr上调用template <std::size_t size, std::size_t I> struct value_getter { template <typename T> static double& get(T arr, bool *signs) { return value_getter<size, I+1>::template get(arr[signs[I]], signs); } };

template <std::size_t size> struct value_getter<size, size> {
    static double& get(double& arr, bool * signs) {
        return arr;
    }
};

基本情况再次微不足道。

  io.on('connection', function (socket) {
    socket.on('join', function(user) {
      //list of connected users
      connected_users.push({socket_id: socket.id, email: user.email});
      socket.join(user.email);
    });
    ...

Demo(C array)