基于范围的for循环通过非常量文字c ++
Range based for loop through non-const literal c++
编译器上下文:我正在使用 GDB v8.3 Ubuntu
和选项 g++ -Im -O2 -std=c++0x
.
进行编译
我经常需要为两个或三个对象完成一些循环,所以我使用包含乱码的基于范围的 for 循环将表达式包装起来。
在 Python3 中看起来像:
a = [1,2,3]
b = [4,5,6]
for v in (a,b):
func(v)
在 C++ 中,这显然不是那么简单。据我所知,使用 {a,b}
创建某种类型的初始化列表,因此转换无法正常工作。在我的尝试中,我遇到了这种情况,但不明白我如何正确地通过引用传递并且它也是可变的,因为我的编译器抱怨这必然是常量。
vector<int> a {1,2,3};
vector<int> b {4,5,6};
for(auto& v: {a,b}) // error non-const
func(v);
根据您的 python 程序,您似乎想要遍历所有向量,但对每个向量都有一个可变引用。您可以使用指针来做到这一点:
for(auto *v: {&a, &b}) // iterate over pointers to the vectors
func(*v); // dereference the pointers to get mutable
// references to the vectors
这是一个demo。
int x,y;
for(int& i:{std::ref(x),std::ref(y)}){
i=7;
}
auto&
不起作用,您必须为每个元素重复 std::ref
。
另一个技巧是:
auto action=[&](auto&foo){
// code
};
action(v1);
action(v2);
你可以这样写:
void foreach_arg(auto&&f, auto&&...args){
((void)f(decltype(args)(args)),...);
}
或c++20之前的版本更多字符,然后:
auto action=[&](auto&foo){
// code
};
foreach_arg(action, v1, v2);
如果你想要第一个提到的参数,你可以这样做:
auto foreacher(auto&&...args){
return [&](auto&&f){
((void)f(decltype(args)(args)),...);
};
}
并得到:
foreacher(v1,v2)([&](auto&v){
// loop body
});
对于任何拼写错误,我们深表歉意。正在编写失眠代码,尚未经过测试。
decltype
在这种情况下是一个简短的 std::forward
等价物(带有 auto&&
args;对于其他一些声明它不起作用)。
auto
函数参数是 c++20 东西。
然后,...
是逗号折叠执行,一个c++17东西。
auto
lambda 的参数是 c++14 的东西。
所有内容都可以替换为 c++11 结构(在这种情况下),但代价是更加冗长。
编译器上下文:我正在使用 GDB v8.3 Ubuntu
和选项 g++ -Im -O2 -std=c++0x
.
我经常需要为两个或三个对象完成一些循环,所以我使用包含乱码的基于范围的 for 循环将表达式包装起来。
在 Python3 中看起来像:
a = [1,2,3]
b = [4,5,6]
for v in (a,b):
func(v)
在 C++ 中,这显然不是那么简单。据我所知,使用 {a,b}
创建某种类型的初始化列表,因此转换无法正常工作。在我的尝试中,我遇到了这种情况,但不明白我如何正确地通过引用传递并且它也是可变的,因为我的编译器抱怨这必然是常量。
vector<int> a {1,2,3};
vector<int> b {4,5,6};
for(auto& v: {a,b}) // error non-const
func(v);
根据您的 python 程序,您似乎想要遍历所有向量,但对每个向量都有一个可变引用。您可以使用指针来做到这一点:
for(auto *v: {&a, &b}) // iterate over pointers to the vectors
func(*v); // dereference the pointers to get mutable
// references to the vectors
这是一个demo。
int x,y;
for(int& i:{std::ref(x),std::ref(y)}){
i=7;
}
auto&
不起作用,您必须为每个元素重复 std::ref
。
另一个技巧是:
auto action=[&](auto&foo){
// code
};
action(v1);
action(v2);
你可以这样写:
void foreach_arg(auto&&f, auto&&...args){
((void)f(decltype(args)(args)),...);
}
或c++20之前的版本更多字符,然后:
auto action=[&](auto&foo){
// code
};
foreach_arg(action, v1, v2);
如果你想要第一个提到的参数,你可以这样做:
auto foreacher(auto&&...args){
return [&](auto&&f){
((void)f(decltype(args)(args)),...);
};
}
并得到:
foreacher(v1,v2)([&](auto&v){
// loop body
});
对于任何拼写错误,我们深表歉意。正在编写失眠代码,尚未经过测试。
decltype
在这种情况下是一个简短的 std::forward
等价物(带有 auto&&
args;对于其他一些声明它不起作用)。
auto
函数参数是 c++20 东西。
然后,...
是逗号折叠执行,一个c++17东西。
auto
lambda 的参数是 c++14 的东西。
所有内容都可以替换为 c++11 结构(在这种情况下),但代价是更加冗长。