C++ 可变模板到数组访问的无递归扩展

C++ 可变模板到数组访问的无递归扩展,c++,c++11,variadic-templates,C++,C++11,Variadic Templates,考虑以下非类型可变模板函数: 模板 在偏移量处无效写入(易失性字符*p){ } 模板 在偏移量处无效写入(易失性字符*p){ p[OFF]=1; 在偏移量(p)处写入; } 它使用递归方法在模板参数包中指定的偏移量处写入1 在C++11中,如果不使用递归,例如通过一次扩展整个包,是否可以简洁地编写此代码?您可以使用折叠表达式(从C++17开始),以索引顺序传递偏移量: template<size_t ... Indices> void foo(std::index_sequence

考虑以下非类型可变模板函数:

模板
在偏移量处无效写入(易失性字符*p){
}
模板
在偏移量处无效写入(易失性字符*p){
p[OFF]=1;
在偏移量(p)处写入;
}
它使用递归方法在模板参数包中指定的偏移量处写入1

在C++11中,如果不使用递归,例如通过一次扩展整个包,是否可以简洁地编写此代码?

您可以使用折叠表达式(从C++17开始),以
索引顺序传递偏移量:

template<size_t ... Indices>
void foo(std::index_sequence<Indices...>,volatile char* p){
    ( (p[Indices] = 1),... );
}

int main(){
    char* p = new char[3];
    foo(std::index_sequence<0,1,2>(),p);

是的,仅使用C++11结构是可能的

template <size_t... OFFs>
void write_at_offsets(volatile char *p) {
    dummyfunc((p[OFFs] = 1, 0) ...) ;  
}
模板
在偏移量处无效写入(易失性字符*p){
dummyfunc((p[OFFs]=1,0)…);
}
dummyfunc
是任何忽略其参数的旧变量函数


不直接传递赋值结果,因为现在不推荐将赋值结果用于易失性变量(尽管C++11中没有这种方法)。

在这种简单的情况下,您可以使用常规循环:

template <std::size_t... OFFs>
void write_at_offsets(volatile char *p) {
    for (std::size_t i : {OFFs}) {
        p[i] = 1;
    }
}
模板
在偏移量处无效写入(易失性字符*p){
对于(std::size_t i:{OFFs}){
p[i]=1;
}
}
在C++11/C++14中还有一些技巧可以模拟C++17的某些折叠表达式:

template <std::size_t... OFFs>
void write_at_offsets(volatile char *p) {
    const int dummy[] = {0, (p[OFFs] = 1, 0)...};
    static_cast<void>(dummy); // Avoid warning for unused variable
}
模板
在偏移量处无效写入(易失性字符*p){
常量int dummy[]={0,(p[OFFs]=1,0);
static_cast(dummy);//避免对未使用的变量发出警告
}
而C++17只是

template <std::size_t... OFFs>
void write_at_offsets(volatile char *p) {
    (p[OFFs] = 1, ...);
}
模板
在偏移量处无效写入(易失性字符*p){
(p[OFFs]=1,…);
}

如果没有std::index\u序列,它不是也能工作吗?(我的意思是-更接近OPs代码。)我摆弄了你的例子:@Scheff Nice version:),你是对的,在我的例子中索引序列在某种程度上是冗余的。是的,这就是我在C++17中使用的,但这里我仅限于C++11。@BeeOnRope添加了C++11版本。请注意,计算顺序未指定,从左到右。@Jarod42您是对的,这可能是个问题。
template <std::size_t... OFFs>
void write_at_offsets(volatile char *p) {
    (p[OFFs] = 1, ...);
}