2017-12-01 3 views
1

Ich habe die folgende ArtConvert Tupels Variante

using MyTuple=std::tuple<std::vector<char>,std::vector<double>,std::vector<int>>; 

Wie eine Meta-Funktion zu schreiben, die MyTuple auf den folgenden Typ umwandeln?

std::variant<std::monostate,char,double,int> 
+0

Haben Sie versucht, etwas zu schreiben? Wo steckst du fest? – Barry

+1

Es macht keinen Sinn, wie man ein solches 'Tupel' in eine solche' Variante' umwandelt. Da einige oder alle dieser "Vektoren" Daten haben können, ist nicht klar, was der Inhalt der "Variante" wäre. Und wenn sie mehrere Elemente haben, wie würde die äquivalente "Variante" das speichern? –

+0

@NicolBolas OP fragte nach einer * meta * -Funktion für die Typberechnung –

Antwort

1
#include <vector> 
#include <tuple> 
#include <variant> 

template <typename Tuple> 
struct get_variant; 

template <typename... Ts> 
struct get_variant<std::tuple<Ts...>> 
{ 
    using type = std::variant<std::monostate, typename Ts::value_type ...>; 
}; 


using MyTuple = std::tuple<std::vector<char>,std::vector<double>,std::vector<int>>; 
using MyVariant = typename get_variant<MyTuple>::type; 

using Expected = std::variant<std::monostate,char,double,int>; 
static_assert(std::is_same_v<Expected, MyVariant>); 

live example

1

Sie können eine Funktionsdeklaration verwenden (keine Definition erforderlich), ein bisschen Vorlage Maschinen und decltype, das zu tun.
Als Beispiel ist dies eine Lösung, die auf die genaue Anzahl der Vektoren stecken nicht (aber man kann es leicht erzwingen, wenn Sie möchten):

template<typename... T> 
std::variant<std::monostate, T...> 
f(std::tuple<std::vector<T>...>); 

template<typename T> 
using to_variant = decltype(f(std::declval<T>())); 

hier ein minimal ist, funktionierendes Beispiel:

#include<tuple> 
#include<variant> 
#include<vector> 
#include<utility> 
#include<type_traits> 

template<typename... T> 
std::variant<std::monostate, T...> 
f(std::tuple<std::vector<T>...>); 

template<typename T> 
using to_variant = decltype(f(std::declval<T>())); 

using MyTuple = std::tuple<std::vector<char>,std::vector<double>,std::vector<int>>; 

int main() { 
    static_assert(std::is_same_v< 
     to_variant<MyTuple>, 
     std::variant<std::monostate,char,double,int> 
    >); 
} 

Sehen Sie es auf und laufen auf wandbox.