For循环的变量-值初始化

时间:2020-08-28 18:02:22

标签: c++ for-loop

这个问题的答案来自@fredoverflow:Multiple Counter Problem In For Loop

所以我有很多变量和它们的值,以便传递throw函数。例如:

 bool a, b, c;
 string string_a, string_b, string_c;
 a = foo(string_a);
 b = foo(string_b);
 c = foo(string_c);

代替手动编写所有内容,我可以采用以下方式创建for循环:

for (struct {bool boo; string str;} loop: {{a, string_a}, {b, string_b}, {c, string_c}}){
    loop.boo = foo(loop.str);
}

它看起来不像是合法的变量分配方式,还是我在这里错过了几个符号? 这样的技巧被认为是一种好习惯吗?

2 个答案:

答案 0 :(得分:1)

std::transform可能会有所帮助。

std::vector<string> src = {string_a, string_b, string_c};
std::vector<bool> dest(src.size());

std::transform(src.begin(), src.end(), dest.begin(), foo);

要让它修改变量,您可以使用std::for_each进行以下操作:

std::vector<std::pair<bool*, string*> > targets = {{&a, &string_a}, {&b, &string_b}, {&c, &string_c}};
std::for_each(targets.begin(), targets.end(), [](auto& p){ *p.first = foo(*p.second); });

或带有for语句:

for(auto loop: std::vector<std::pair<bool*, string*> > {{&a, &string_a}, {&b, &string_b}, {&c, &string_c}}) {
    *loop.first = foo(*loop.second);
}

答案 1 :(得分:0)

使用(C ++ 20)初始化语句将结构化绑定与基于范围的for循环组合

从C ++ 20开始,您可以使用range-based for loop初始化语句,可以将其与structured bindings结合使用,如下所示:

#include <ios>
#include <iostream>
#include <string>
#include <string_view>
#include <utility>

bool foo(std::string_view s) {
    return s == "b";  
}

int main() {
    bool a{false}, b{false}, c{false};
    std::string string_a{"a"}, string_b{"b"}, string_c{"c"};
    
    for (typedef std::pair<bool&, std::string_view> P;
         auto [res, str] : {P{a, string_a}, {b, string_b}, {c, string_c}}) {
        res = foo(str);
    }
    
    std::cout << std::boolalpha << a << " " << b << " " << c << "\n";
        // false true false
}

利用typedef declarations are init-statements(不是 alias-declarations 的情况)来声明P实用程序别名的事实,该别名又用于在初始值设定项列表中键入推导在该范围内,基于for的范围会迭代(并绑定值)。

在C ++ 20之前,您可以简单地将实用程序类型别名放在循环之前:

using P = std::pair<bool&, std::string_view>;
for (auto [res, str] : {P{a, string_a}, {b, string_b}, {c, string_c}}) {
    res = foo(str);
}

或完全删除实用程序类型别名:

for (auto [res, str] : {
        std::pair<bool&, std::string_view>{a, string_a},
        {b, string_b}, {c, string_c}}) {
    res = foo(str);
}

这样的技巧被认为是一种好习惯吗?

答案的这一部分可能会进入基于意见的领域,尽管这不一定适用于上面的代码段,但肯定会对in the answer you refer to使用的技术如此(“ Hackety hack hack” < / em>)。句法组合是如此聪明,以至于它们最终被称为“技巧” ,对于特定的作者而言,它们可能最终因其自身的利益而变得过于聪明,并且阻碍了代码库的清晰和理解。代码以及其他(当前和将来的)维护者。