jro*_*rok 5 c++ parsing stdvector most-vexing-parse
考虑这个例子:
#include <iostream>
#include <string>
#include <vector>
#include <iterator>
int main()
{
std::string sen = "abc def ghi jkl";
std::istringstream iss(sen);
std::vector<std::string> // declaration in question
vec(std::istream_iterator<std::string>(iss),
std::istream_iterator<std::string>());
std::copy(vec.begin(), vec.end(),
std::ostream_iterator<std::string>(std::cout, "\n"));
}
Run Code Online (Sandbox Code Playgroud)
编译器在调用时抛出错误 std::copy
request for member 'begin' in 'vec', which is of non-class type...
我可以解决这个错误:
std::istream_iterator<std::string> it_begin(iss);
std::istream_iterator<std::string> it_end;
std::vector<std::string> vec(it_begin, it_end);
Run Code Online (Sandbox Code Playgroud)
或者在每个参数周围加上括号,如下所示:
std::vector<std::string>
vec((std::istream_iterator<std::string>(iss)),
(std::istream_iterator<std::string>()));
Run Code Online (Sandbox Code Playgroud)
甚至在C++ 11中使用新的统一初始化:
std::vector<std::string> vec { /*begin*/, /*end*/ };
Run Code Online (Sandbox Code Playgroud)
为什么编译器将示例中的声明解析为函数声明?我知道最烦恼的解析,但我认为只有空参数列表才会发生.我也想知道为什么第二种解决方法有效.
它仍然是最令人烦恼的解析.
std::vector<std::string> // return type
vec( // function name
std::istream_iterator<std::string>(iss), // param 1: an iterator called (iss), or just iss
std::istream_iterator<std::string>() // param 2: unnamed function
); // returning iterator
Run Code Online (Sandbox Code Playgroud)
geordi说:
<tomalak> << ETYPE_DESC(vec); std::vector<std::string> vec(std::istream_iterator<std::string>(iss), std::istream_iterator<std::string>());
<geordi> lvalue function taking a istream_iterator<string, char, char_traits<char>, long> , a pointer to a nullary function returning a istream_iterator<string, char, char_traits<char>, long> , and returning a vector of strings
Run Code Online (Sandbox Code Playgroud)
实际上,它的关键在于你的参数名称可以在它们周围加上括号(即iss→ (iss))而不改变声明的语义.有时.
如您所示,使用另一组围绕该类型的括号来强制将第一个参数(以及因此第二个参数)解析为表达式而不是声明.
如果有帮助,还要考虑:
void foo(int (x)) {
cout << x;
}
int main() {
foo(42);
}
Run Code Online (Sandbox Code Playgroud)