2016-07-19 6 views
2

Ist es möglich, eine Parameterliste zur Kompilierzeit statisch zu "entrollen", indem man in jedem "Unroll" -Schritt einen Parameter verwendet? Ich denke, variadische Vorlagen sind die Art und Weise mit partieller Vorlage Spezialisierung kombiniert zu gehen, aber ich kann dieses Beispiel nicht bekommen laufen:Zugriff auf den ersten Parameter im Parameterpaket?

#include <iostream> 

char static const text1[] = "Foo"; 
char static const text2[] = "FooBar"; 

template <char const * TEXT, unsigned int N, char const *... REST, unsigned int... Ns> 
void doStuff() { 
    std :: cout << TEXT << "-" << N << std :: endl; 
    doStuff<REST..., Ns...>(); 
} 

template <char const * TEXT, unsigned int N> 
void doStuff() { 
    std :: cout << TEXT << std :: endl; 
} 

void doStuff() {} 

int main() { 
    doStuff<text1,3,text2,5>(); 
    return 0; 
} 

Meine erwartete Ausgabe Foo-3\nFooBar-5 Allerdings wäre Klirren ++ 3.8 gibt mir:

error: no matching function for call to 'doStuff' 
     doStuff<text1,3,text2,5>(); 
     ^~~~~~~~~~~~~~~~~~~~~~~~ 
test.cpp:7:6: note: candidate template ignored: invalid explicitly-specified argument for template 
     parameter 'REST' 
void doStuff() { 
    ^
test.cpp:13:6: note: candidate template ignored: invalid explicitly-specified argument for template 
     parameter 'N' 
void doStuff() { 
    ^
+0

Können Sie 'const char *' und 'N' in eine Art packen , um eine Sequenz von diesem gepackten Typ zu haben? – Jarod42

+0

Ja kann ich, aber ich möchte einige zusätzliche Parameter an die Funktion wie z. 'template void doStuff (char test) {}' – user1228633

Antwort

2

In C++ 17, könnten Sie so etwas wie

template <char const * TEXT, unsigned int N> 
void doStuff() { 
    std::cout << TEXT << "-" << N << std::endl; 
} 

template <auto v1, auto v2, auto ... values> 
void doStuff() 
{ 
    std :: cout << v1 << "-" << v2 << std :: endl; 
    doStuff<values...>(); 
} 

zur Zeit müssen Sie Ihre Werte durch Paar packen tun:

template<const char* S, int N> 
struct pairValue { 
    static constexpr const char* s = S; 
    static constexpr int n = N; 
}; 

template <typename ... Ts> 
void doStuff() 
{ 
    const int dummy[] = {0, ((std::cout << Ts::s << "-" << Ts::n << std::endl), 0)...}; 
    static_cast<void>(dummy); // Avoid warning for unused variable. 
} 

Und es nennen:

doStuff<pairValue<text1, 3>, pairValue<text2, 5>>(); 
+0

Nun, +1 für die 'auto', liebe es von C++ 17. – skypjack

+0

Danke für den Tipp. Jetzt entpacken Sie die Liste jedoch direkt in einem Schritt. Gibt es eine Möglichkeit, jeder Funktion zusätzliche Parameter zur Verfügung zu stellen, vielleicht rekursiv? So etwas wie 'template void doStuff (char test) {}'? – user1228633

+0

Nicht klar, was Sie wollen. – Jarod42

0

Sie sie verwenden können als Parameter um ihn zu arbeiten:

#include <iostream> 
#include<type_traits> 

char static const text1[] = "Foo"; 
char static const text2[] = "FooBar"; 

constexpr void doStuff() {} 

template <typename T, typename U, typename... O> 
constexpr 
std::enable_if_t< 
    std::is_same<T, const char *>::value 
    and std::is_same<U, int>::value 
> doStuff(T str, U num, O... o) { 
    std :: cout << str << "-" << num << std :: endl; 
    doStuff(o...); 
} 

int main() { 
    doStuff(text1,3,text2,5); 
    return 0; 
}