2017-07-12 4 views
5

Je suis en train de réaliser ce qui suit:modèle de modèle de C paramètre non type

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

où une fonction possible pourrait être:

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

donc alors l'utilisation de recherche serait:

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

ne vous inquiétez pas au sujet de la mise en œuvre de trouver, je vous demande simplement sur la façon de faire « template <typename> bool Function_ » comme la partie bool est actuellement invalide en C++.

toute aide est appréciée!

EDIT:

ici est un exemple des raisons pour lesquelles je ne peux pas passer le "is_pointer" à la fonction:

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); 
} 

ce produit l'erreur du compilateur:

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

+1

Vous pouvez prendre 'is_pointer' comme paramètre de modèle de modèle normal et accéder à son membre' value' dans le corps. –

+0

malheureusement j'utilise une approche plus boost :: hana où toutes les structures "is_pointer" sont réellement des fonctions –

+1

Si elles sont réellement des fonctions, vous pouvez en prendre une en tant que paramètre de type normal. Je ne pense pas que vous pourriez montrer un exemple motivant? –

Répondre

2

any help is appreciated!

Vous pouvez simplement envelopper vos fonctions au sein de foncteurs.
Par exemple minimal, travail:

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); 
} 

Si vous ne pouvez pas les modifier directement, créer foncteurs que l'attaquant tout à la bonne fonction par une méthode membre de constexpr statique.

+0

J'essayais d'éviter cela (comme je vais devoir le faire avec toutes les fonctions maintenant), mais je ne vois pas d'autre moyen alors merci! –

1

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

En ce qui je sais, argume modèle-modèle Les nts sont une chose complètement différente. Ils sont destinés aux conteneurs, pas aux fonctions. Donc class, pas bool.

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

Votre exemple ne fonctionne pas parce que add_pointer est une fonction de modèle, de sorte que lorsque vous appelez

apply(add_pointer, t_i); 

le compilateur ne sait pas quelle version (type T) de add_pointer à utiliser.

Une solution peut être explicite, comme dans l'exemple simplifié suivant

#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); 
} 

mais je comprends que l'explicitation int(*)(std::tuple<int>) est une grande douleur dans le cul.

Vous pouvez simplifier un peu en utilisant le fait que vous passez t afin que vous puissiez déduire le type de l'argument reçu par la fonction, mais (pour une solution générique) je ne sais pas comment éviter d'expliciter le type de retour de la fonction (peut-être il est possible, mais (en ce moment) Je ne sais pas.

vous pouvez donc simplifier l'appel comme suit

apply<int>(add_pointer, t_i); 

et ce qui suit est un petit exemple plus général

#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

Merci pour votre aide, mais ce n'est pas vraiment la mise en œuvre que je suis après, j'utilise mon propre tuple qui est juste un type tuple no values, puis je passe une fonction ou une variable template qui est ensuite évaluée avec tous les types différents dans un Tuple de types. –