c 从模板参数中解包参数包

新手上路,请多包涵

如何实现我想要的下面?我要解包的参数包不在函数参数列表中,而是在模板参数列表中。

 #include <iostream>
#include <array>

const std::size_t SIZE = 10;

template <int...ARGS>
std::array<bool, SIZE> func() {
    std::array<bool, SIZE> b;
    // I want to set b[n] = true, where n takes on all values from ARGS...
    // what to put in here???
    return b;
}

// Example of what I want to achieve:
int main() {
    const std::array<bool, SIZE> b = func<1,3,7>();
    // I want b[1]==true, b[3]==true, b[7]==true, all others false
    for (int x: b) std::cout << x << std::endl;
}

我必须为 func 使用这种形式(而不是 func(1,3,7))才能让我的更大程序工作(我正在处理多重继承问题)。

原文由 prestokeys 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 662
2 个回答

递归模板解决方案:

 // recursive helper struct
template <int n, int First, int ...Rest>
struct helper {
  static void funcImpl(std::array<bool, SIZE>& temp) {
    temp[First] = true;
    helper<n - 1, Rest...>::funcImpl(temp);
  }
};

// partial specialization to catch base case
template <int First>
struct helper<0, First> {
  static void funcImpl(std::array<bool, SIZE>& temp) {
    temp[First] = true;
  }
};

template <int ...Args>
std::array<bool, SIZE> func() {
    std::array<bool, SIZE> b = {}; // 0 inititalize array
    helper<sizeof...(Args) - 1, Args...>::funcImpl(b);
    return b;
}

编辑: 受iavr解决方案启发的超级简化版本:

 template <int... A>
std::array<bool, SIZE> func() {
    std::array<bool, SIZE> b = {};
    auto values = {A...};
    std::for_each(values.begin(), values.end(), [&](int n){b[n] = true;});
    return b;
}

原文由 Sam Cristall 发布,翻译遵循 CC BY-SA 3.0 许可协议

活的例子

这是 func 的实现:

 template <int... A, int... N>
std::array<bool, sizeof...(N)>
func(sizes <N...>)
{
    return std::array<bool, sizeof...(N)>{{in <N, A...>()...}};
}

template <int... A>
std::array<bool, SIZE>
func() { return func <A...>(range <SIZE>()); }

where sizes represents an int sequence, range <S> constructs sequence 0,...,S-1 and in<N, A...>() checks whether number N 是按顺序排列的 A... (实例中的定义)。

这不是最有效的(编译方式)实现方式,因为对于 N... 的每个元素,我们需要扫描包 A... 。最好并行扫描包 A...L... ,修改函数 in() 。但无论如何,这更容易想到和写下来。

原文由 iavr 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题