2017-07-12 17 views
5

ich folgend zu erreichen versuchen:C++ Template-Template-nicht-Typ-Parameter

template<template<typename> bool Function_, typename ... Types_> 
constexpr auto find(Tuple<Types_ ... >) noexcept 
{ 
    // ... 
} 

, wo eine mögliche Funktion sein könnte:

template<typename T> 
inline constexpr bool is_pointer_v = is_pointer<T>::value; 

so ist, dann wäre die Verwendung von Fund sein:

Tuple<int, char, void *> t; 
find<is_pointer_v>(t); 

Mach dir keine Sorgen über die Implementierung von finden, ich bin nur gefragt, wie zu tun "template <typename> bool Function_" wie der bool Teil in C++ derzeit ungültig ist.

jede Hilfe ist willkommen!

EDIT:

hier ist ein Beispiel dafür, warum ich die "is_pointer", um die Funktion nicht passieren kann:

template<typename T_> 
constexpr auto add_pointer(Type<T_>) noexcept 
{ return type_c<T_ *>; } 

template<typename F_, typename T_> 
constexpr auto apply(F_ f, Type<T_> t) noexcept 
{ 
    return f(t); 
} 

int main(void) 
{ 
    Type<int> t_i; 
    apply(add_pointer, t_i); 
} 

dies den Compiler-Fehler erzeugt:

error: no matching function for call to ‘apply(< unresolved overloaded function type >, sigma::meta::Type&)’ apply(add_pointer, t_i);

+1

Sie könnten 'is_pointer' als normalen Vorlagen-Vorlagenparameter verwenden und auf ihr' value'-Element im Hauptteil zugreifen. –

+0

Leider benutze ich einen boost :: hana styled Ansatz, bei dem alle "is_pointer" Strukturen eigentlich Funktionen sind –

+1

Wenn sie tatsächlich Funktionen sind, können Sie einen als normalen Typparameter nehmen. Ich nehme nicht an, dass Sie ein motivierendes Beispiel zeigen könnten? –

Antwort

2

any help is appreciated!

Sie können Ihre Funktionen einfach in Funktoren einfügen.
Als minimal, Arbeitsbeispiel:

template<typename> 
struct Type {}; 

template<typename> 
struct type_c {}; 

template<typename T_> 
struct add_pointer { 
    static constexpr auto invoke(Type<T_>) noexcept 
    { return type_c<T_ *>{}; } 
}; 

template<template<typename> class F_, typename T_> 
constexpr auto apply(Type<T_> t) noexcept { 
    return F_<T_>::invoke(t); 
} 

int main(void) { 
    Type<int> t_i; 
    apply<add_pointer>(t_i); 
} 

Wenn Sie sie nicht direkt ändern können, erstellen functors, die alles an der richtigen Funktion durch ein statisches constexpr Mitglied Verfahren übermitteln.

+0

Ich habe versucht, dies zu vermeiden (wie ich es jetzt mit jeder einzelnen Funktion tun muss), aber ich sehe keinen anderen Weg, also danke! –

1

I am just asking about how to do "template < typename > bool Function_" as the bool part is invalid in c++ currently.

Soweit ich weiß, Vorlage-Vorlage argume Es ist eine ganz andere Sache. Sie sind für Container bestimmt, nicht für Funktionen. Also class, nicht bool.

here is an example of why I can't pass the "is_pointer" to the function

Ihr Beispiel funktioniert nicht, weil add_pointer eine Template-Funktion ist, also wenn Sie

nennen
apply(add_pointer, t_i); 

der Compiler nicht weiß, welche Version (welche Art T) von add_pointer zu verwenden.

Eine Lösung kann

#include <tuple> 
#include <iostream> 

template <typename T> 
constexpr auto add_pointer(std::tuple<T>) noexcept 
{ std::cout << "add_pointer" << std::endl; return 0; } 

template <typename F, typename T> 
constexpr auto apply(F f, std::tuple<T> t) noexcept 
{ return f(t); } 

int main(void) 
{ 
    std::tuple<int> t_i { 1 }; 

    apply<int(*)(std::tuple<int>)>(add_pointer, t_i); 
} 

wie im folgenden vereinfachten Beispiel explizit es sein, aber ich verstehe, dass int(*)(std::tuple<int>) explizieren ein großer Schmerz im Arsch ist.

Sie können ein wenig vereinfachen mit der Tatsache, dass Sie t übergeben, so können Sie den Typ des Arguments von der Funktion erhalten abgeleitet, aber (für eine generische Lösung) Ich weiß nicht, wie Sie den Rückgabetyp explizit vermeiden folgende ist ein wenig allgemeines Beispiel für die Funktion (vielleicht ist es möglich, aber (in diesem Moment) ich weiß nicht.

Sie also den Anruf vereinfachen können als

apply<int>(add_pointer, t_i); 

und folgen

#include <tuple> 
#include <iostream> 

template <typename ... Ts> 
constexpr auto add_pointer(std::tuple<Ts...> const &) noexcept 
{ std::cout << "add_pointer" << std::endl; return 0; } 

template <typename R, typename ... Ts, 
      typename F = R(*)(std::tuple<Ts...> const &)> 
constexpr auto apply(F f, std::tuple<Ts...> t) noexcept 
{ return f(t); } 

int main(void) 
{ 
    std::tuple<int> t_i { 1 }; 

    apply<int>(add_pointer, t_i); 
} 
+0

Danke für deine Hilfe, aber es ist wirklich nicht die Implementierung, die ich mache. Ich benutze mein eigenes Tupel, das einfach ist ein Typ Tupel keine Werte, und dann gebe ich eine Template-Funktion oder Variable, die dann mit allen verschiedenen Typen in einem Tuple von Typen ausgewertet wird. –