c ++向量构造函数的奇怪行为

时间:2014-08-27 21:57:49

标签: c++ vector stl

我注意到了c ++ vector构造函数的一些奇怪行为,有人可以为我解释一下吗?感谢。

代码段1有效:

#include <string>
#include <vector>
#include <iostream>
#include <istream>
#include <ostream>
#include <iterator>
#include <sstream>
#include <algorithm>

using namespace std;

int main()
{
  string str = "The quick brown fox";

  stringstream strstr(str);

  istream_iterator<string> start(strstr);
  vector<string> results(start, istream_iterator<string>());

  ostream_iterator<string> oit(cout, "\n");
  copy(results.begin(), results.end(), oit);
}

但代码段2不会:

#include <string>
#include <vector>
#include <iostream>
#include <istream>
#include <ostream>
#include <iterator>
#include <sstream>
#include <algorithm>

using namespace std;

int main()
{
  string str = "The quick brown fox";

  stringstream strstr(str);

  vector<string> results(istream_iterator<string>(strstr), istream_iterator<string>());

  ostream_iterator<string> oit(cout, "\n");
  copy(results.begin(), results.end(), oit);
}

唯一的区别是向量构造函数中的第一个参数。

2 个答案:

答案 0 :(得分:5)

Most vexing parse

 vector<string> results(istream_iterator<string>(strstr), istream_iterator<string>());

被解析为名为results的函数,返回vector并获取一个名为strstr的{​​{1}}类型参数和一个未命名参数类型“函数不带参数返回istream_iterator<string>“。

将其更改为:

istream_iterator<string>

或者您可以添加括号,但它也不太可读:

vector<string> results = vector<string>(istream_iterator<string>(strstr), istream_iterator<string>());

正如BenjaminLindley在评论中所建议的那样,更可读/更不容易出错的方法是在单独的语句中声明迭代器:

vector<string> results( ( istream_iterator<string>(strstr) ), istream_iterator<string>());

注意:

有些编译器,比如clang,就此发出警告:

  

警告:括号被解除歧义为函数声明[-Wvexing-parse]

答案 1 :(得分:0)

编译器会考虑此语句

vector<string> results(istream_iterator<string>(strstr), istream_iterator<string>());

作为具有返回类型vector<string>和两个参数的函数声明,第一个类型为istream_iterator<string>,第二个类型为“返回类型为istream_iterator<string>且没有参数的函数” 。改为使用

vector<string> results( ( istream_iterator<string>(strstr) ), istream_iterator<string>());

vector<string> results( { istream_iterator<string>(strstr), istream_iterator<string>() } );

然后更清楚的是,声明符可以括在括号中。所以你可以写例如

int f( int (x), int (y) );

int ( x ) = 10;