2011-12-02 152 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