2016-02-21 20 views
5

讀了一大篇True Story: Efficient Packing後,我試圖執行的元組由我自己鍛鍊:電話功能不明確時,不相干的類型定義別名

#include <type_traits> 
#include <utility> 
#include <functional> 

template< std::size_t I, typename T > 
struct tuple_leaf { T value; }; 

template< std::size_t I, typename T > 
T & get(tuple_leaf< I, T > & leaf) 
{ return leaf.value; } 

template< typename Is, typename ...Ts > 
struct tuple_base; 

template< std::size_t ...Is, typename ...Ts > 
struct tuple_base< std::index_sequence<Is...>, Ts... > 
    : tuple_leaf< Is, Ts >... 
{ 
    using tuple_base_t = tuple_base; 
    template< typename ...Args, typename = std::enable_if_t< (sizeof...(Ts) == sizeof...(Args)) > > 
    tuple_base(Args &&... args) 
     : tuple_leaf< Is, Ts >{std::forward<Args>(args)}... 
    { ; } 
}; 

#if 0 
template< typename ...Ts > 
struct tuple 
    : tuple_base< std::index_sequence_for<Ts...>, Ts... > 
{ 
    using tuple_base_t = typename tuple::tuple_base_t; 
    using tuple_base_t::tuple_base_t; 
    using tuple_base_t::operator = ; 
}; 
#else 
// terse 
template< typename ...Ts > 
using tuple = tuple_base< std::index_sequence_for<Ts...>, Ts... >; 
#endif 

template< typename ...Args > 
tuple< Args &&... > 
forward_as_tuple(Args &&... args) 
{ return {std::forward<Args>(args)...}; } 

#include <tuple> 

int 
main() 
{ 
    tuple<int> t(1); 
    auto f = forward_as_tuple(t); 
    (void)f; 
    return 0; 
} 

Live example

實施forward_as_tuple我決定後,從類模板改變tuple類型的定義別名模板基類模板,因爲所有我從分裂到需要自身tuple類其實現類tuple_base只是std::index_sequence_for可變參數模板類型參數包 - 別名模板正是適合此目的的工具。這樣做,我得到一個錯誤(#if 0情況下)後:

error: call to 'forward_as_tuple' is ambiguous

它看起來很奇怪的我,因爲別名模板無助和呼籲從同一個命名空間類型另一方面forward_as_tuple - 我希望ADL應當爲上述案例工作。

如何解釋#if 1#if 0版本的代碼之間的區別?

+0

'的std :: index_sequence_for'成爲一個函數調用的參數類型的類型模板參數,所以'std'由ADL檢查。 BTW。如果直接使用元組',你會得到同樣的錯誤 –

+0

@PiotrSkotnicki微妙的時刻。我始終記住,ADL僅適用於函數參數類型,但也適用於模板參數。 – Orient

+0

@PiotrSkotnicki tuple_base ,int>>,tuple_base ,int>>是函數參數。 'std :: index_sequence_for'在裏面很深。即它不是頂級模板名稱。有關係嗎? – Orient

回答

3

Adl導致在傳遞的類型和傳遞的類型的模板參數中查找。

元組非別名有其類型和自己作爲地方尋找ADL。

元組的別名情況下在其模板參數列表std::index_sequence。除了您的forward_as_tuple之外,這會導致std::forward_as_tuple被考慮。它們同樣很好匹配,並且發生模糊。

如@Piotr上述意見,tuple<std::string>出現此問題,即使在非摺疊殼體指出。

相關問題