英文:
template for loop with non-const arguments
问题
在cpp中,你可以使用两个秘籍来有效地在模板参数上实现一个for循环,编译器将接受这样做。如下所示。
template<size_t k> void increment(size_t* v, size_t& i){ v[k]=i*i++; }
int main(){
const size_t N = 10;
size_t v[N], i=0;
// for(size_t k=0;k<N;++k){ increment<k>(v,i); } // 这样不会工作
// 所以我们写下以下内容
[v,i]<std::size_t... Is>(std::index_sequence<k...>){ // 这行是第一个秘籍
(increment<k>(v,i), ...); // 循环体
}(std::make_index_sequence<N>{}); // 这行是第二个秘籍
for(size_t k=0;k<N;++k){ std::cout << v[k] << " , "; }
}
英文:
In cpp you can use two cheat codes to effectively have a for-loop over template arguments, which the compiler will accept. This is shown below.
#include <iostream>
#include <memory>
template<size_t k> void increment(size_t* v, size_t& i){ v[k]=i*i++; }
int main(){
const size_t N = 10;
size_t v[N], i=0;
// for(size_t k=0;k<N;++k){ increment<k>(v,i); } // this would not work
// so we write the following instead
[v,i]<std::size_t... Is>(std::index_sequence<k...>){ // this line is the first cheat code
(increment<k>(v,i), ...); // loop body
}(std::make_index_sequence<N>{}); // this line is the second cheat code
for(size_t k=0;k<N;++k){ std::cout << v[k] << " , "; }
}
Question: The code won't compile because in the line loop body, the compiler requires v,i to be const. But as the example points out, I do not want them const. Thus, I am asking for that cheat code, which makes it work. If multiple cheat codes exist, I want the shortest.
答案1
得分: 6
The mutable
keyword can be used to allow a lambda expression to modify objects it captures by value.
You also need to capture v
by reference or increment
will be called on a copy of v
and have no visible effect.
Live example: https://godbolt.org/z/4xbPe4MdP
#include <iostream>
#include <memory>
template<size_t k> void increment(size_t* v, size_t& i){ v[k] = i * i++; }
int main(){
constexpr std::size_t N = 10;
std::size_t v[N];
[&v, i = std::size_t{}]<std::size_t... k>(std::index_sequence<k...>) mutable
{
(increment<k>(v, i), ...);
}(std::make_index_sequence<N>{});
for(std::size_t k = 0; k < N; ++k){ std::cout << v[k] << " , "; }
}
英文:
The mutable
keyword can be used to allow a lambda expression to modify objects iT captures by value.
You also need to capture v
by reference or increment
will be called on a copy of v
and have no visible effect.
Live example : https://godbolt.org/z/4xbPe4MdP
#include <iostream>
#include <memory>
template<size_t k> void increment(size_t* v, size_t& i){ v[k]=i*i++; }
int main(){
constexpr std::size_t N = 10;
std::size_t v[N];
[&v,i = std::size_t{}]<std::size_t... k>(std::index_sequence<k...>) mutable
{
(increment<k>(v,i), ...);
}(std::make_index_sequence<N>{});
for(std::size_t k=0;k<N;++k){ std::cout << v[k] << " , "; }
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论