讀了一大篇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;
}
實施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
版本的代碼之間的區別?
'的std :: index_sequence_for'成爲一個函數調用的參數類型的類型模板參數,所以'std'由ADL檢查。 BTW。如果直接使用元組',你會得到同樣的錯誤 –
@PiotrSkotnicki微妙的時刻。我始終記住,ADL僅適用於函數參數類型,但也適用於模板參數。 – Orient
@PiotrSkotnicki tuple_base,int>>,tuple_base ,int>>是函數參數。 'std :: index_sequence_for'在裏面很深。即它不是頂級模板名稱。有關係嗎? –
Orient