樣品實施
template<typename T1, typename T2>
struct simple_pair {
simple_pair (T1 const& v1, T2 const& v2) // (1)
: first (v1)
, second (v2)
{ }
template<class U, class V>
simple_pair (U&& v1, V&& v2) // (2)
: first (std::forward<U> (v1))
, second (std::forward<V> (v2))
{ }
T1 first;
T2 second;
};
即使盡管提供過載(1)
和(2)
似乎是多餘的,但有些情況下第二個不可用,並且第一個不僅是首選,而且是第實際上需要。
考慮到我們想在構造函數simple_pair
的構造函數中構造一些或兩個值,而沒有第一個重載,我們將不得不第二次指定至少一個類型。
T val;
simple_pair<T, U> p1 { {}, {} }; // only (1) is applicable
simple_pair<T, U> p2 { val, {} }; // only (1) is applicable
simple_pair<T, U> p3 { T {}, U {} }; // can use (1) and (2), but this require a lot of typing
替代實現
如果我們不是有使用的東西的下面,我們可以繞過「多餘」重載,因爲編譯器會後來才知道我們」是什麼類型的實行d喜歡在需要這些信息的情況下構建。
template<typename T1, typename T2>
struct simple_pair {
template<class U = T1, class V = T2>
simple_pair (U&& v1, V&& v2)
: first (std::forward<U> (v1))
, second (std::forward<V> (v2))
{ }
T1 first;
T2 second;
};
T val;
simple_pair<T, U> p1 { {}, {} }; // legal
simple_pair<T, U> p2 { val, {} }; // legal
simple_pair<T, U> p3 { T {}, U {} }; // legal
爲什麼不std::pair
陳述使用可替代實現方式來實現?
我們只能猜測,但可能是因爲向後兼容性和指定它現在的方式使庫實現者的實現變得容易。
通過具有兩個獨立的過載一個可以很容易地通過使用宏(查看是否我們使用c++11
(或更高版本))有條件地將它,而不是選擇加入有條件出來,然後再添加其他禁用template<class U, class V> simple_pair (U&&, V&&)
過載。
進一步潛在原因
1.肯定得不多,但心裏很不舒服..它不會傷害是一個有點迂腐.. ;-)
有可能對某些類型的可移動的,但不可複製。另一方面,某些類型也可以是可複製的,但不可移動。這兩個構造函數允許'pair'與這兩種類型一起使用。 – Cornstalks
@Cornstalks第二個構造函數可以處理這兩種情況,它使用通用引用。見http://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers – DanielKO
看看[這個簡短的例子](http://ideone.com/D1iHwn),它顯示在所有常見情況下調用第二個變體。不過,我相信在極少數情況下,調用第二次重載是不可能的。但這是一個有趣的問題。 – Excelcius