Dopo aver letto di un grande articolo True Story: Efficient Packing ho cercato di implementare tuple da solo come l'esercizio fisico:chiamata alla funzione è ambiguo quando il tipo di irrilevante definito come alias
#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;
}
Dopo l'implementazione di forward_as_tuple
decido di modifica la definizione del tipo dal modello di classe a alias modello del modello di classe base, poiché tutto ciò di cui ho bisogno dalla suddivisione in classe tuple
e la sua classe di implementazione tuple_base
è solo std::index_sequence_for
per il tipo di parametri del modello variadic pack - alias modello è esattamente lo strumento adatto a questo scopo. Dopo aver fatto che ho un errore (#if 0
caso):
error: call to 'forward_as_tuple' is ambiguous
Sembra strano per me, perché modello alias non fa nulla e d'altra parte forward_as_tuple
chiamato per il tipo dallo stesso spazio dei nomi - Speravo che ADL dovrebbe funzionare per il caso sopra di sicuro.
Come spiegare la differenza tra le versioni di codice #if 1
e #if 0
?
'std :: index_sequence_for' diventa un argomento modello tipo del tipo dell'argomento di una chiamata di funzione, quindi' std' viene esaminato da ADL. BTW. Avrai lo stesso errore se usi 'tupla' direttamente –
@PiotrSkotnicki Momento sottile. Tengo sempre a mente che ADL è solo per tipi di argomenti di funzione, ma è anche per i parametri del modello. – Orient
@PiotrSkotnicki 'tuple_base, int>>, tuple_base , int>>' è l'argomento della funzione. 'std :: index_sequence_for' è nel profondo. Cioè non è il nome del top template. Importa? –
Orient