2016-08-08 7 views
8

C++ 11 Standard haben std::conditional<> Vorlage für die Typauswahl durch die einige boolesche Bedingung zum Zeitpunkt des Compilers. Wie wird die gleiche Operation ausgeführt, aber für den Initialisierungswert für die Initialisierung der Variablen? Ähnlich wie type a = (exp) ? first_value : second_value;.Wie erfolgt die Initialisierung der bedingten Variablen zur Compilerzeit?

ich meine Vorlage:

template<bool B, typename T> 
inline constexpr T&& conditional_initialize(T&& i1, T&& i2) { 
    return B ? std::move(i1) : std::move(i2); 
} 

Aber es kann nur für POD-Typen verwendet werden: int a = conditional_initialize<true>(1, 2);. Bei der Array-Initialisierung wird diese Vorlage mit Fehler kompiliert. Falsche Kompilierung Beispiel: int a[] = conditional_initialize<true>({1, 2}, {3,4,5});

Fehlermeldung: no matching function for call to 'conditional_initialize(<brace-enclosed initializer list>, <brace-enclosed initializer list>)';

Wer kann mir helfen mit Vorlage?

+2

@AndyG, ist es 'std :: initializer_list ' ' – alexeykuzmin0

+0

int a [] = conditional_initialize ({1, 2}, {3,4,5});' Das kann nicht funktionieren, können Sie nicht kopieren oder verschieben Konstruieren Sie eingebaute Arrays. –

+2

@ alexeykuzmin0 wäre es in der Tat, aber leider [Vorlagen können nicht abgeleitet werden 'std :: initializer_list'] (http://stackoverflow.com/a/12431810/3233393). – Quentin

Antwort

8
template<class T, std::size_t N, std::size_t M, bool b> 
std::array<T, b?N:M> 
conditional_array(std::array<T, N>&& lhs, std::array<T, M>&& rhs) { 
    return std::move(std::get<b?0:1>(std::tie(lhs, rhs))); 
} 

das gibt Ihnen:

auto a = conditional_array<int,2,3,true>({{1, 2}}, {{3,4,5}}); 

die in der Nähe ist.

Im Allgemeinen sind {} Konstrukte keine Ausdrücke, sie können nicht perfekt durch irgendeinen Mechanismus durch eine andere Variable weitergeleitet werden.

Wir können auch erhalten:

auto a = cond_init<true>(make_array(1,2), make_array(3,4,5)); 

mit ein bisschen mehr Arbeit.

template<bool Test, class A, class B> 
std::conditional_t<Test,A,B> 
cond_init(A a, B b) { 
    return std::move(std::get<Test?0:1>(std::tie(a,b))); 
} 
template<class T0, class...Ts> 
std::array< std::decay_t<T0>, sizeof...(Ts)+1 > 
make_array(T0&& t0, Ts&&...ts) { 
    return {{std::forward<T0>(t0), std::forward<Ts>(ts)...}}; 
} 

Ich habe diese constexpr nicht gemacht, weil faul. Kein

+0

** Yakk **, wie wäre es mit einer solchen Vorlage - http://cpp.sh/6swua? – 23W

+0

@ 23W ist das nicht nur mein 'cond_init' und manueller' make_array' Fall mit kleinen Änderungen? Ich war faul darin, dass ich nicht von 'std :: tie 'auditieren konnte, und dergleichen sind ausreichend' conexpr 'für jede Version von C++, die du benutzt hast. – Yakk

+0

Ja ist es.Es ist eine Modifikation Ihres Codes für einzelne Ansätze für einfache Typen und C++ - Standard-Arrays (die unterschiedliche Typen für verschiedene Größen sind). – 23W

Verwandte Themen