2015-10-01 41 views
8

我試圖通過使用boost map_list_of將地圖內容傳遞給一個參數來構造一個對象,該對象將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構造函數?

有沒有一種更好的方法來實現這一點,短缺makeBlah函數將構造一個對象Blah,因爲它看起來像我將不得不做的?

(順便說一句,我使用map_list_of使測試輸入數據創建更可讀的這樣做在單元測試)

回答

5

map_list_of不創建一個容器,但它創建了一個

匿名列表可被轉化到任何標準容器

的轉換通過一個模板用戶定義的轉換操作來完成:

template< class Container > 
    operator Container() const; 

因此,在構造函數的上下文中,它不能推導出是否轉換爲map<int, int>Blah。爲了避免這種情況,你可以,例如,添加一個虛擬構造函數的參數:

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)); 
} 

隨着makeBlah你沒有這樣的歧義。

或者,你可以採取列表類型爲構造函數的參數,然後內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()',你可以轉儲boost代碼並使用'initializer_list'初始化映射。 –

2

因爲C++ 11的到來,boost::assign已變得不那麼引人注目比它。

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

應該這樣做。

相關問題