带有两个参数的向量构造函数被解析为函数声明

Vector constructor with two parameters is parsed as a function declaration

本文关键字:构造函数 声明 函数 向量 参数 两个      更新时间:2023-10-16

考虑这个例子:

#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"));
}

编译器在调用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);

或者在每个参数周围加上括号,如下所示:

std::vector<std::string>
vec((std::istream_iterator<std::string>(iss)),
    (std::istream_iterator<std::string>()));

或者甚至使用C++11:中的新的统一初始化

std::vector<std::string> vec { /*begin*/, /*end*/ };

编译器为什么要将示例中的声明解析为函数声明我知道大多数令人烦恼的解析,但我认为这只会发生在空参数列表中。我还想知道为什么第二种变通方法有效。

它仍然是最麻烦的解析。

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

乔治迪说:

<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

实际上,它的关键是,您的参数名称周围可以有括号(即iss(iss)),而不会更改声明的语义。有时

如图所示,使用另一组括号来包围类型,以强制将第一个参数(以及第二个参数)解析为表达式而不是声明。


如果有帮助,也可以考虑:

void foo(int (x)) {
   cout << x;
}
int main() {
   foo(42);
}

输出为42