关于最令人烦恼的解析的令人困惑的细节
我的问题是如何将以下行解析为函数声明:
vector<int> v(istream_iterator<int>(cin), istream_iterator<int>());
我了解最令人烦恼的解析的大部分细节以及为什么第二个临时迭代器可以解释为返回迭代器且不带参数的函数的类型,但我不明白的是为什么第一个临时迭代器可以解释为类型。它代表什么类型?我的想法是,这将是某种函数类型,但我看不出名称 cin 是如何使用的。它是否声明该参数是一个名为 cin
的 istream_iterator
?如果是这样,这是否意味着您可以任意将函数的参数名称括起来?如果是这样,为什么?
My question is how the following line can be parsed as a function declaration:
vector<int> v(istream_iterator<int>(cin), istream_iterator<int>());
I understand most of the details of the Most Vexing Parse and why the second temporary iterator can be interpreted as a type that is a function returning an iterator and taking no arguments, but what I don't get is why the first temporary iterator can be interpreted as a type. What type does it represent? My thought is that it would be some sort of function type, but I can't see how the name cin
gets used. Is it declaring that the parameter is an istream_iterator<int>
named cin
? If so, does that mean that you can arbitrarily parenthesize the names of arguments to functions? And if so, why?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
istream_iterator(cin)
与istream_iterator; 完全相同。 cin
但带有多余的括号。这种声明符语法是从 C 继承的,我认为甚至 C 的发明者(Ken Thompson?)也将其描述为错误。istream_iterator<int>(cin)
is exactly the same asistream_iterator<int> cin
but with superfluous parens. This declarator syntax was inherited from C, and I think even the inventor of C (Ken Thompson?) described it as a mistake.我是否已经说过我(非常)喜欢 Clang ?
只需尝试以下(简化的代码)
在新重新命名的 LLVM Try Out 中(嗯,它只是从 llvm-gcc 变为铛)。
你会得到:
因此,@john 是对的,
int(i)
被解释为int i
,即函数的命名参数。Did I already said that I liked Clang (a lot) ?
Just try the following (simplified code)
In the newly rebrandished LLVM Try Out (well, it just went from llvm-gcc to clang).
And you get:
And therefore, @john is right,
int(i)
is interpreted asint i
, ie a named parameter to the function.是的,它是参数名称。而且,是的,您可以添加一组括号,因为有时您必须这样做。
如果参数是函数指针,则需要这样写
void (*f)()
。编写标准的人没有花费宝贵的时间来准确指出允许或实际需要括号的情况,因此标准只是说您可以拥有它们。
Yes, it is the parameter name. And, yes you can add a set of parenthesis, because sometimes you have to.
If the parameter is a function pointer,
void (*f)()
you need to write it like that.The people writing the standard have not spent their precious time pointing out exactly the cases where the parenthesis are allowed or actually required, so the standard just says that you can have them.
标准 (2003) 中有一个名为
歧义解决
的部分专门讨论此类语法。我想如果您自己阅读该部分,我不需要进一步解释,因为它非常清楚,有很多例子!所以你开始吧:
There is a section called
Ambiguity resolution
in the Standard (2003) which is dedicated to such syntaxes. I think I don't need to explain it further if you read the section yourself, for its very clear with lots of examples!So here you go: