2017-07-11 66 views
6

下面的代碼編譯的G ++(各種版本)的罰款,但未能就譁++ - 與我的系統上的libC++ 3.4:std :: map默認構造函數是否顯式?

#include <map> 
#include <string> 

std::map<std::string, std::string> f() { 
    return {}; 
} 

int main() { 
    auto m = f(); 
} 

鐺標誌着以下問題:

x.cpp:6:12: error: chosen constructor is explicit in copy-initialization 
    return {}; 
      ^~ 
/usr/local/Cellar/llvm34/3.4.2/lib/llvm-3.4/bin/../include/c++/v1/map:838:14: note: constructor declared here 
    explicit map(const key_compare& __comp = key_compare()) 
      ^

事實上,包括文件聲明構造函數爲explicit。但是它並沒有在我的C++ 11草案標準中標記出來。這是鏗鏘聲++/libC++中的錯誤嗎?我無法找到相關的錯誤報告。

+1

它看起來是'explicit'畢竟(至少直到C++ 14):http://en.cppreference.com/w/cpp/container/map/map –

+0

在當前的工作草案[n4659](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4659.pdf#subsubsection.26.4.4.1)中,它也被標記爲「明確的'。 –

+0

@KonradRudolph在你的例子和錯誤信息中,你沒有調用拷貝構造函數,問題出現在這之前 - 當你試圖默認構造一個'std :: map'。 –

回答

9

在C++ 14之前沒有空構造函數。缺省建設std::map<Key, Value, Compare, Allocator>explicit 2個默認參數,直到C++ 14:

explicit map(const Compare& comp = Compare(), 
       const Allocator& alloc = Allocator()); 

C++ 14後,我們已經從之前調用explicit構造(現在做非explicit空的默認構造函數沒有默認Compare參數):

map() : map(Compare()) {} 
explicit map(const Compare& comp, 
       const Allocator& alloc = Allocator()); 

所以你的例子就只能是C++ 14後有效。

來源:http://en.cppreference.com/w/cpp/container/map/map

+0

謝謝,非常有道理。所以g ++ 4.8(用'-std = C++ 1')接受它是錯誤的,對嗎? –

+0

@KonradRudolph是的,GCC在與C++ 11兼容的標準庫編譯時應該拒絕這個。 –

+0

不夠公平,但不是一個構造函數,其參數在技術上默認都是默認的構造函數 - 假設沒有「真正的」默認c'tor? –