2011-12-02 137 views
1

可能重复:
Why is it an error to use an empty set of brackets to call a constructor with no arguments?奇怪的编译错误

小块代码代码不能成功编译上
微软的Visual Studio 2005

#include <iterator> 
#include <algorithm> 
#include <vector> 
#include <iostream> 

int main() 
{ 
    std::vector<int> a; 
    std::istream_iterator<int> be(std::cin); 
    std::istream_iterator<int> en(); 
    std::copy(be, en, std::back_inserter(a));  
} 

但这一个是好的

#include <iterator> 
#include <algorithm> 
#include <vector> 
#include <iostream> 

int main() 
{ 
    std::vector<int> a; 
    std::istream_iterator<int> be(std::cin); 
    std::istream_iterator<int> en; //Same to upon, only here less '()' 
    std::copy(be, en, std::back_inserter(a));  
} 
+3

你得到的错误是什么?正如乔布斯所说 - *只是不要这样做!* :-) – littleadv

回答

4

在第一种情况下en被声明为函数,而不是变量。这是C++语法中存在的很多陷阱之一,很难解析C++程序。

所应用的规则或多或少“如果它既可以作为声明,也可以作为定义被解析,那么它就被认为是声明”,并被Scott Meyers命名为“most vexing parse”。在你的情况下,第二行可以看到类似于

inf foo(); 

因此被认为是一个函数声明。请注意,这非常相同的陷阱可以更加微妙:

double x = 3.141592654; 
int y(int(x)); 

这里的第二行也是一个函数的声明,因为语言规则说,在这里,围绕x括号可以忽略不计,因此意义是int y(int x);

+2

它被称为[“最令人头痛的解析”](http://en.wikipedia.org/wiki/Most_vexing_parse)。 '网上有很多*参考。 –

+0

我想补充一点,尽管可能在VS2005上没有,问题中给出的版本,这个陷阱可以通过使用新的C++ 11初始化程序列表来避免:'std :: istream_iterator 是{std :: cin} '和'std :: istream_iterator en {}'。 –

+1

@JoachimPileborg:C++的主要问题是IMO的复杂性,增加更多的复杂性似乎对我来说不是一个合理的解决方案。如果你需要知道很多奇怪的规则,写出正确的C++代码移动到一种语言甚至更陌生的规则是不是一个前进的步骤。 – 6502