从模板实参中解包形参包
c++ Unpacking parameter pack from template arguments
如何实现我想要的?我要解包的形参包不在函数实参列表中,而是在模板实参列表中。
#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))来让我的大程序工作(我正在处理多个继承问题)。
递归模板解:
// 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;
}
这里有一个更简单的解决方案,不需要额外的东西,只是:
struct _do { template <typename... T> _do(T&&...) { } };
template <int... A>
std::array<bool, SIZE> func() {
std::array<bool, SIZE> b = {};
_do{b[A] = true...};
return b;
}
假设数组先初始化,然后填充。我以前的解决方案在编译时计算所有的值,并用它们直接初始化数组。因此,这可能是更快的编译和较慢的运行。
从c++ 17开始,可以使用折叠表达式:
template <std::size_t... ARGS>
constexpr std::array<bool, SIZE> func() {
std::array<bool, SIZE> b{};
((b[ARGS] = true), ...); // fold expression
return b;
}
演示对于c++ 11和c++ 14,我更喜欢使用一个未命名的lambda,像这样:
template <std::size_t... ARGS>
std::array<bool, SIZE> func() {
std::array<bool, SIZE> b{};
[](...){}(b[ARGS] = true...);
return b;
}
参见实例
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>()); }
其中sizes
表示int
序列,range <S>
构造序列0,...,S-1
, in<N, A...>()
检查数字N
是否在序列A...
中(定义见实例)。
这不是最有效的(编译明智的)实现方式,因为对于N...
的每个元素,我们都需要扫描A...
包。最好并行扫描A...
、L...
包,并修改in()
函数。但无论如何,这更容易理解和写下来
相关文章:
- 使用mem_fun_ref if成员函数需要多个形参
- 通过类的模板形参特化成员模板结构
- 非类型引用形参/实参
- 哪个模板形参在boost::shared_ptr构造函数中使用一个原始指针
- 如何确保迭代器模板形参与模板类的模板形参具有相同的数据类型
- 如何在编译时通过模板形参默认值的名称/指针获取函数的类型
- c++:候选模板被忽略:模板形参显式指定的参数无效
- c++中作为形参的指针
- 哪种方法更适合为函数提供编译时间常数?函数实参与模板形参
- 包含void*结构的函数的Const正确性和形参
- 传递boost::函数,该函数接受一个模板实参作为默认为NULL的形参
- 展开std::函数模板中的形参包
- 将函数形参的实参解包到c++模板类
- 带默认模板实参的形参包
- 在模板中使用模板形参作为实参
- 模板继承:没有依赖模板形参的实参
- 用const实参重载实参演绎的c++模板函数
- 扩展非类型形参包来定义带有非类型形参的内部类模板是否合法?
- 函数指针的形参类型的模板实参演绎涉及未演绎的形参包
- 从模板实参中解包形参包