2017-07-11 4 views
6

次のコードは、G上の罰金コンパイル++(さまざまなバージョン)が、打ち鳴らす++に失敗した - 私のシステム上++のlibcと3.4:ファイルが含まれ、実際std :: mapのデフォルトコンストラクタは明示的ですか?

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()) 
      ^

#include <map> 
#include <string> 

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

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

打ち鳴らすには、次のような問題をマークコンストラクタをexplicitと宣言します。 しかし、私のC++ 11ドラフト標準ではそのようにマークされていません。これはclang ++/libC++のバグですか?私は関連するバグレポートを見つけることができませんでした。

+1

に見えます: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>のデフォルトの建設は、C++ 14になるまで2つのデフォルトパラメータでexplicitにマークされている:

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の後に有効となります。

出典:それは(少なくとも、14 C++まで)すべての後に `explicit`あるようhttp://en.cppreference.com/w/cpp/container/map/map

+0

ありがとう、完璧な意味があります。だからg ++ 4.8( '-std = C++ 1'と一緒に)はそれを受け入れるのが間違っていました、正しい? –

+0

@ KonradRudolphはい、GCCは、C++ 11準拠の標準ライブラリでコンパイルするときにこれを拒否したはずです。 –

+0

十分ですが、パラメータがすべてデフォルトのコンストラクタに技術的にデフォルト設定されているコンストラクタではありません - 実際のデフォルトのc'torはないと仮定します。 –

関連する問題