是否可以在for循环中声明两个不同类型的变量?

时间:2010-04-22 00:07:17

标签: c++ scope declaration for-loop

是否可以在C ++的for循环的初始化主体中声明两个不同类型的变量?

例如:

for(int i=0,j=0 ...

定义了两个整数。我可以在初始化主体中定义intchar吗?怎么会这样做?

8 个答案:

答案 0 :(得分:261)

不 - 但从技术上讲,有一种解决方法(不是我实际使用它,除非被迫):

for(struct { int a; char b; } s = { 0, 'a' } ; s.a < 5 ; ++s.a) 
{
    std::cout << s.a << " " << s.b << std::endl;
}

答案 1 :(得分:200)

不可能,但你可以这样做:

float f;
int i;
for (i = 0,f = 0.0; i < 5; i++)
{
  //...
}

或者,使用其他括号明确限制fi的范围:

{
    float f; 
    int i;
    for (i = 0,f = 0.0; i < 5; i++)
    {
       //...
    }
}

答案 2 :(得分:103)

C ++ 17 是!您应该使用structured binding declaration。 gcc-7和clang-4.0(clang live example)支持该语法。这允许我们像这样解压缩一个元组:

for (auto [i, f, s] = std::tuple{1, 1.0, std::string{"abc"}}; i < N; ++i) {
    // ...
}

以上将给你:

  • int i设置为1
  • double f设置为1.0
  • std::string s设置为"abc"

确保#include <tuple>这种声明。

如果要为类型命名,可以像tuple一样输入std::string中的确切类型。例如:

auto [vec, i32] = std::tuple{std::vector<int>{3, 4, 5}, std::int32_t{12}}

C ++ 14 :您可以添加基于类型的std::get,与C ++ 11(下面)相同。因此,在下面的示例中,您可以使用std::get<0>(t)而不是std::get<int>(t)


C ++ 11 std::make_pair允许您执行此操作,以及std::make_tuple可用于两个以上的对象。

for (auto p = std::make_pair(5, std::string("Hello World")); p.first < 10; ++p.first) {
    std::cout << p.second << std::endl;
}

std::make_pair将在std::pair中返回两个参数。可以使用.first.second访问这些元素。

对于两个以上的对象,您需要使用std::tuple

for (auto t = std::make_tuple(0, std::string("Hello world"), std::vector<int>{});
        std::get<0>(t) < 10;
        ++std::get<0>(t)) {
    std::cout << std::get<1>(t) << std::endl; // cout Hello world
    std::get<2>(t).push_back(std::get<0>(t)); // add counter value to the vector
}

std::make_tuple是一个可变参数模板,它将构造任意数量参数的元组(当然还有一些技术限制)。可以使用std::get<INDEX>(tuple_object)

索引访问元素

在for循环体中,您可以轻松地对对象进行别名,但仍需要使用.firststd::get作为for循环条件并更新表达式

for (auto t = std::make_tuple(0, std::string("Hello world"), std::vector<int>{});
        std::get<0>(t) < 10;
        ++std::get<0>(t)) {
    auto& i = std::get<0>(t);
    auto& s = std::get<1>(t);
    auto& v = std::get<2>(t);
    std::cout << s << std::endl; // cout Hello world
    v.push_back(i); // add counter value to the vector
}

C ++ 98和C ++ 03 您可以明确命名std::pair的类型。但是,没有标准的方法可以将其概括为两种以上类型:

for (std::pair<int, std::string> p(5, "Hello World"); p.first < 10; ++p.first) {
    std::cout << p.second << std::endl;
}

答案 3 :(得分:14)

您不能在初始化中声明多种类型,但可以指定多种类型E.G。

{
   int i;
   char x;
   for(i = 0, x = 'p'; ...){
      ...
   }
}

只需在自己的范围内声明它们。

答案 4 :(得分:1)

有关嵌套多个for循环的其他方法,请参阅“Is there a way to define variables of two types in for loop?”。另一种方式优于Georg的“结构技巧”的优点是它(1)允许你混合使用静态和非静态局部变量,(2)它允许你拥有不可复制的变量。缺点是它的可读性要低得多,而且效率可能会降低。

答案 5 :(得分:0)

定义一个宏:

#define FOR( typeX,x,valueX,  typeY,y,valueY,  condition, increments) typeX x; typeY y; for(x=valueX,y=valueY;condition;increments)

FOR(int,i,0,  int,f,0.0,  i < 5, i++)
{
  //...
}

请记住,您的变量范围也不会以这种方式在for循环中。

答案 6 :(得分:0)

我认为最好的方法是xian's answer

但是...


#嵌套用于循环

这种方法很脏,但是可以解决所有版本。

所以,我经常在宏函数中使用它。

for(int _int=0, /* make local variable */ \
    loopOnce=true; loopOnce==true; loopOnce=false)

    for(char _char=0; _char<3; _char++)
    {
        // do anything with
        // _int, _char
    }

其他1。

它也可以用于declare local variablesinitialize global variables

float globalFloat;

for(int localInt=0, /* decalre local variable */ \
    _=1;_;_=0)

    for(globalFloat=2.f; localInt<3; localInt++) /* initialize global variable */
    {
        // do.
    }

其他2。

很好的例子:具有宏功能。

(如果best approach不能使用,因为它是for循环宏)

#define for_two_decl(_decl_1, _decl_2, cond, incr) \
for(_decl_1, _=1;_;_=0)\
    for(_decl_2; (cond); (incr))


    for_two_decl(int i=0, char c=0, i<3, i++)
    {
        // your body with
        // i, c
    }

#if语句技巧

if (A* a=nullptr);
else
    for(...) // a is visible

如果您想初始化为0nullptr,则可以使用此技巧。

但是我不建议您这样做,因为阅读困难。

似乎是个错误。

答案 7 :(得分:-1)

此外,您也可以在C ++中像下面这样使用。

int j=3;
int i=2;
for (; i<n && j<n ; j=j+2, i=i+2){
  // your code
}