2016-07-11 57 views
3

我不知道如何調用的std::make_optional這兩個重載得到解決:函數模板重載分辨率混亂

template< class T > 
constexpr std::optional<std::decay_t<T>> make_optional(T&& value); 

template< class T, class... Args > 
constexpr std::optional<T> make_optional(Args&&... args); 

我知道沒有明確的模板參數像make_optional(123)將調用第一個調用,但如何make_optional<int>(123)?哪些超載將被選擇,以及按照什麼規則?

UPDATE:如果我寫說make_optional<string>("hello world"),我會調用第二個重載(即使字符串文字可以被隱式轉換爲string),是否正確?

+1

庫(和名稱空間)在哪裏聲明它們? ['std :: experimental'](http://en.cppreference.com/w/cpp/header/experimental/optional)似乎只定義了第一個。 – Nawaz

+0

@Nawaz:'make_optional'的第二個重載來自[P0032(PDF)](http://wg21.link/P0032),它[在Oulu之前轉發給LWG](https://issues.isocpp.org /show_bug.cgi?id=100),顯然。雖然P0091可能會使它過時,所以他們可能沒有采用它。所以目前納瓦茲是正確的:第二次超載不存在。 –

+0

@NicolBolas [它存在](https://github.com/cplusplus/draft/commit/1882aa320a101fcfdb7a6d4de40197982209ce30)。 –

回答

2

重載分辨率從確定可行候選項開始,選擇具有最佳轉換順序的項目,然後查看tiebreakers列表。


make_optional(123)僅具有一個可行的候選,因爲T處於第二過載的非推導出上下文。因此,它是最好的可行候選人。


make_optional<int>(123)給了我們兩個可行的候選人:

  • make_optional(int&&)[T=int]
  • make_optional<int>(int&&)[T=int, Args={int}]

功能採取同樣的參數(int&&),所以他們同樣平凡可用相同的轉換序列進行。第一個重載是比第二個重載更專用的函數模板(因爲它只接受一個參數而不是可變參數包),所以它是首選。


make_optional<string>("hello world")給了我們兩個可行的候選人:

  • make_optional(string&&)[T=string]
  • make_optional<string>(const char(&)[12])[T=string, Args={const char (&)[12]}]

這裏,兩個函數不採取同樣的觀點 - 第一需要一個string&&(這將需要用戶定義的字符串轉換)和th e秒需要一個const char(&)[12](這是一個完全匹配)。因此,第二次過載具有更好的轉換順序並且是優選的。