Nach einem großen Artikeln lesen True Story: Efficient Packing ich versuchte, von mir zu implementieren Tupel als Übung:Call-Funktion ist nicht eindeutig, wenn irrelevant Typ als Alias definiert
#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;
}
Nach der Implementierung von forward_as_tuple
mir entscheiden, Ändern Sie die Definition von tuple
Typ von Klassenvorlage bis Alias-Vorlage von seiner Basisklasse Vorlage, weil alles, was ich brauche von der Teilung in Klasse tuple
selbst und seine Implementierung Klasse tuple_base
ist nur std::index_sequence_for
für variadic Vorlagentyp Parameter pack - Alias-Vorlage ist genau das geeignete Werkzeug für diesen Zweck. Nachdem ich, dass ich einen Fehler (#if 0
Fall):
error: call to 'forward_as_tuple' is ambiguous
Es sieht für mich seltsam, denn alias Vorlage nichts tut, und auf der anderen Seite forward_as_tuple
für Typen aus dem gleichen Namensraum genannt - ich hatte gehofft, dass ADL sollte für den obigen Fall sicher funktionieren.
Wie erklärt man den Unterschied zwischen #if 1
und #if 0
Versionen des Codes?
'std :: index_sequence_for' wird zu einem Typvorlagenargument vom Typ des Arguments eines Funktionsaufrufs, so dass' std' von ADL untersucht wird. Übrigens. Sie erhalten den gleichen Fehler, wenn Sie 'tuple' direkt –
@PiotrSkotnicki Subtilen Moment verwenden. Ich denke immer daran, dass ADL nur für Funktionsargumenttypen, aber auch für Vorlagenparameter ist. – Orient
@PiotrSkotnicki 'tuple_base, int>>, tuple_base , int>>' ist das Funktionsargument. 'std :: index_sequence_for' ist tief drin. I.e. Es ist kein Top-Template-Name. Ist es wichtig? –
Orient