IAE*_*IAE 15 c++ for-loop c++11
来自c ++ 0x维基百科网站:
int my_array[5] = {1, 2, 3, 4, 5};
for (int &x : my_array) {
x *= 2;
}
Run Code Online (Sandbox Code Playgroud)
那么为什么这段代码不起作用呢?
int main(int argc, char* argv[])
{
for (char *arg : argv)
{
// Do something.
}
}
Run Code Online (Sandbox Code Playgroud)
错误:
main.cpp:36: error: no matching function for call to ‘begin(char**&)’
Run Code Online (Sandbox Code Playgroud)
我在Ubuntu 11.10上使用Qt和g ++ 4.6.1.
附加信息
R. *_*des 23
通常情况下,我做的第一件事argc
和argv
是这样的:
std::vector<std::string> arguments(argv, argv + argc);
Run Code Online (Sandbox Code Playgroud)
现在我有一个可以使用的字符串向量,我不仅可以轻松使用基于范围的for循环,还可以使用C++标准库工具.
for(std::string& s : arguments) {
// do stuff...
}
Run Code Online (Sandbox Code Playgroud)
维基百科代码有效,因为类型my_array
是数组类型的变量.原始代码不起作用,因为argv
它不是数组.语法char* argv[]
可能使它看起来像是一个数组,但这只是一个C语法的悲伤工件.char* argv[]
是完全相同一样char** argv
.argv
不是一个数组; 它实际上只是一个指针.
基于范围的for循环适用于:
begin()
并end()
返回迭代器的类型;begin
和end
,可以这样调用begin(x)
和end(x)
,与x
是,你要遍历的事情.如您所见,指针不是此列表的一部分.
Omn*_*ous 16
你没有,因为系统无法判断argv
编译时有多长.有人可能会找到标准的适当部分来引用你的相关信息.
虽然有一种解决方法,那就是创建一个自定义类来包装argv
.它甚至不是那么难.
class argv_range {
public:
argv_range(int argc, const char * const argv[])
: argc_(argc), argv_(argv)
{
}
const char * const *begin() const { return argv_; }
const char * const *end() const { return argv_ + argc_; }
private:
const int argc_;
const char * const *argv_;
};
Run Code Online (Sandbox Code Playgroud)
以下是您使用它的方式:
for (const char *arg: argv_range(argc, argv)) {
// Do something.
}
Run Code Online (Sandbox Code Playgroud)
是的,我使用了很多const
s.基本上,argv
是一个字符指针数组,其中没有一个应该被修改,每个都指向一个字符串,其中任何一个字符都不应该被修改.
您可以使用 C++20std::span()
或gsl::span()
为以下内容创建视图argv
:
for (auto const arg : std::span(argv, argc)) {
std::cout << arg << '\n';
}
Run Code Online (Sandbox Code Playgroud)
或类似的,使用范围( std::view::counted()
):
for (auto const arg : std::views::counted(argv, argc)) {
std::cout << arg << '\n';
}
Run Code Online (Sandbox Code Playgroud)
或直接使用std::ranges::subrange
:
for (auto const arg : std::ranges::subrange{argv, argv+argc}) {
std::cout << arg << '\n';
}
Run Code Online (Sandbox Code Playgroud)
提出的向量解决方案复制数组(仅指针,而不是字符串1 - 但仍然)。不雅。如果我绝对想强制执行基于范围的循环,我也会尝试使用 argv_range 解决方案。但这会产生很多额外的代码(承认,只有一次,如果您将其写入头文件并保留它,但仍然如此)。
经典循环对我来说似乎很简单,我允许自己发布它,我认为仅仅为了拥有一个基于范围的循环而付出所有这些努力是不值得的......
for (char** a = argv; *a; ++a)
{
// use *a, or if you don't like:
char* arg = *a;
// use arg...
}
Run Code Online (Sandbox Code Playgroud)
或者,如果您以后不再需要 argv 数组:
for (++argv; *argv; ++argv)
{
// use *argv, or if you don't like:
char* a = *argv;
// use a...
}
Run Code Online (Sandbox Code Playgroud)
有一点不同,您可能已经注意到:在第一个变体中,我遍历所有值,在第二个变体中,我省略了第一个(通常是我们在许多情况下不感兴趣的程序名称)。反过来,对于每个:
for (char** a = argv + 1; *a; ++a);
for (; *argv; ++argv);
Run Code Online (Sandbox Code Playgroud)
1这仅适用于,如果使用std::vector<char*>
; 如果使用std::vector<std::string>
,正如实际建议的那样,甚至字符串本身也会被复制!
归档时间: |
|
查看次数: |
6213 次 |
最近记录: |