2015-10-01 5 views
8

私は、を使ってマップの内容を渡すことによって、std::mapをパラメータとして受け取るオブジェクトを作成しようとしています。マップを取得する関数にブーストmap_list_ofを渡すことはできますが、コンストラクタは使用できないのはなぜですか?

これはコンパイルエラーですが、普通の関数で同じ機能を実行しようとするとstd::mapが発生しますが、コンパイルエラーは発生しません。

#include <map> 
#include <boost/assign.hpp> 

struct Blah 
{ 
    Blah(std::map<int, int> data) {} 
}; 

void makeBlah(std::map<int, int> data) {} 

int main() 
{ 
    Blah b(boost::assign::map_list_of(1, 2)(3, 4)); // Doesn't compile. 

    makeBlah(boost::assign::map_list_of(1, 2)(3, 4)); // Compiles fine! 
} 

私が手コンパイルエラーは次のとおりです。

error: call of overloaded ‘Blah(boost::assign_detail::generic_list<std::pair<int, int> >&)’ is ambiguous 
note: candidates are: Blah::Blah(std::map<int, int, std::less<int>, std::allocator<std::pair<const int, int> > >) 
note:     Blah::Blah(const Blah&) 

何曖昧で、どのように来る、それは私の知る限り、同じを持っている通常のfunctoinのmakeBlahには影響しません。 Blahのコンストラクタとしての署名?

Blahのオブジェクトを生成する関数を作成するのに足りないこれを実現する良い方法はありますか? (余談ですが、私はより読みやすいテスト入力データの作成を行うためにmap_list_ofを使用してユニットテストでこれをやっているとして)

答えて

5

map_list_ofは、コンテナを作成しませんが、それは

を作成します

:変換は、テンプレートユーザー定義変換演算子を介して行われ、任意の標準的な容器

に変換することができる

匿名リスト

template< class Container > 
    operator Container() const; 

ので、コンストラクタの文脈では、それはmap<int, int>またはBlahに変換するかどうかを推測することはできません。あなたは、このような曖昧さを持っていないmakeBlah

class Blah 
{ 
    public: 
     Blah(std::map<int, int> data, int) 
     { 
     } 

}; 

void makeBlah(std::map<int, int> data) 
{ 
} 

void myTest() 
{ 
    Blah b(boost::assign::map_list_of(1, 2)(3, 4), 0); 

    makeBlah(boost::assign::map_list_of(1, 2)(3, 4)); 
} 

:これを避けるために、あなたは、例えば、ダミーのコンストラクタパラメータを追加することができます。

また、あなたは、コンストラクタのパラメータとしてリストタイプを取ることができるし、その後Blah以内にそれを使用します。

class Blah 
{ 
    public: 
     Blah(decltype(boost::assign::map_list_of(0, 0)) data) 
      : m(data.to_container(m)) 
     { 
     } 

    std::map<int, int> m; 
}; 
+0

'decltype()'を使うことができますが、ブーストコードをダンプしてマップを初期化するために 'initializer_list'を使うことができます。 –

2

をC++ 11の出現以来、boost::assignはそれがあったほど魅力的になってきています。

Blah b({{1, 2},{3, 4}}); 

とする必要があります。