【问题标题】:Range based for loop in function which passes an array as value [duplicate]函数中基于范围的for循环将数组作为值传递[重复]
【发布时间】:2015-10-27 17:54:15
【问题描述】:

这些天我自己在学习 C++,但我在理解为什么这段代码不能使用 #g++ -std=c++11 source.cpp 编译时遇到了一些问题。实际上,我使用哪个特定标准并不重要,它只是无法编译。

#include <iostream>
#include <string>
using namespace std;
int print_a(char array[])
{
    for(char c : array)
        cout << c;
    cout << endl;
    return 0;
}
int main(void)
{
    char hello[] {"Hello!"};
    print_a(hello);
    return 0;
}

错误信息:

debian@debian:~/Documents$ g++ -std=c++11 source.cpp
source.cpp: In function ‘int print_a(char*)’:
source.cpp:6:15: error: ‘begin’ was not declared in this scope
  for(char c : array)
               ^
source.cpp:6:15: note: suggested alternatives:
In file included from /usr/include/c++/4.9/bits/basic_string.h:42:0,
                 from /usr/include/c++/4.9/string:52,
                 from /usr/include/c++/4.9/bits/locale_classes.h:40,
                 from /usr/include/c++/4.9/bits/ios_base.h:41,
                 from /usr/include/c++/4.9/ios:42,
                 from /usr/include/c++/4.9/ostream:38,
                 from /usr/include/c++/4.9/iostream:39,
                 from source.cpp:1:
/usr/include/c++/4.9/initializer_list:89:5: note:   ‘std::begin’
     begin(initializer_list<_Tp> __ils) noexcept
     ^
/usr/include/c++/4.9/initializer_list:89:5: note:   ‘std::begin’
source.cpp:6:15: error: ‘end’ was not declared in this scope
  for(char c : array)
               ^
source.cpp:6:15: note: suggested alternatives:
In file included from /usr/include/c++/4.9/bits/basic_string.h:42:0,
                 from /usr/include/c++/4.9/string:52,
                 from /usr/include/c++/4.9/bits/locale_classes.h:40,
                 from /usr/include/c++/4.9/bits/ios_base.h:41,
                 from /usr/include/c++/4.9/ios:42,
                 from /usr/include/c++/4.9/ostream:38,
                 from /usr/include/c++/4.9/iostream:39,
                 from source.cpp:1:
/usr/include/c++/4.9/initializer_list:99:5: note:   ‘std::end’
     end(initializer_list<_Tp> __ils) noexcept
     ^
/usr/include/c++/4.9/initializer_list:99:5: note:   ‘std::end’

【问题讨论】:

  • 编译器给你的错误信息是什么?
  • @Davycc,最好​​将错误消息添加到问题中。之后您可以删除评论。

标签: c++ c++11 for-loop


【解决方案1】:

它无法编译的原因是在 C++ 中,函数参数(例如 char array[])被调整char* array。你的函数看起来真的很像

int print_a(char* array)
{
 ....
}

并且基于范围的循环无法处理指针。

一种解决方案是通过引用传递数组。 C++ 不允许您按值传递普通数组。例如,这将接受一个包含 5 个chars 的数组:

int print_a(const char (& array)[5])
{
   for(char c : array) cout << c;
   cout << endl;
   return 42;
}

为了将其推广到不同大小的数组,您可以使用模板:

template <std::size_t N>
int print_a(const char (& array)[N])
{
   for(char c : array) cout << c;
   cout << endl;
   return 42;
}

当然,还有更简单的方法可以打印以空字符结尾的字符串:

char hello[] {"Hello!"};
cout << hello << endl;

还有一些标准库类型可以更轻松地传递字符串或字符缓冲区对象。例如,std::stringstd::vector&lt;char&gt;std::array&lt;char, N&gt;(其中N 是编译时间常数。)

【讨论】:

  • 谢谢!我只是在玩它。这对我来说是一种练习。我同意,有很多更好的方法可以做到这一点,但这是找出基于范围的循环和数组衰减的最简单方法,你不觉得吗?!附言谢谢大家,伙计们。感谢您的帮助!
  • @Davycc 确实是类型调整。当你从一个数组初始化一个指针时会发生衰减。
【解决方案2】:

当您将数组传递给函数时,它会“衰减”为指针。在函数中看起来像这样:int print_a(char *array) {...} 您正在使用的循环类型,称为范围循环,无法处理指针,这是错误的根源(尝试迭代指针是没有意义的)。

要么必须通过引用传递数组,要么只使用常规的 for 循环。

老实说,如果您使用 C++,请使用 C++。使用std::string, or std::vector

【讨论】:

  • 数组只有在传递时衰减,因为函数参数是一个指针。
【解决方案3】:

这里

int print_a(char array[])
{
    for(char c : array)
        cout << c;
    cout << endl;
    return 0;
}

数组衰减到pointer,因为当你传递一个数组是值时,你究竟在做什么将指针传递给数组的第一个元素,并且基于范围的循环不能使用指针,因此你得到的错误。

See this 了解数组是如何衰减的以及解决方案是什么。

你需要使用通过引用或指针传递。

【讨论】:

    猜你喜欢
    • 2014-12-04
    • 1970-01-01
    • 2016-08-26
    • 2017-11-04
    • 2018-12-28
    • 2013-04-01
    • 1970-01-01
    相关资源
    最近更新 更多