2017-07-12 239 views
5

我努力实现以下目标:C++模板模板非类型参数

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

,其中一个可能的功能可能是:

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

所以后来找到的用法是:

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

不用担心执行找不到,我只是在问怎么做“template <typename> bool Function_”因为bool部分目前在C++中无效。

任何帮助表示赞赏!

编辑:

这里是为什么我不能通过 “is_pointer” 给函数的一个例子:

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

这将产生编译器错误:

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

+1

您可以将'is_pointer'作为正常的模板模板参数,并访问其中的'value'成员。 –

+0

不幸的是我使用了更多的boost :: hana风格的方法,其中所有“is_pointer”结构实际上都是函数 –

+1

如果它们实际上是函数,那么可以将其作为普通类型参数。我不认为你可以展示一个激励的例子? –

回答

2

any help is appreciated!

您可以简单地将函数包装在仿函数中。
作为最小的,工作示例:

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

如果你不能直接改变它们,创建通过静态constexpr成员方法都转发到正确的功能仿函数。

+0

我试图避免这种情况(因为我现在必须用每一个功能来完成),但我没有看到另一种方式,所以谢谢! –

1

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

据我所知,template-template argume nts是完全不同的东西。它们用于容器,而不是用于功能。所以class,而不是bool

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

您的例子不工作,因为add_pointer是一个模板函数,所以当你打电话

apply(add_pointer, t_i); 

编译器不知道的add_pointer哪个版本(这类型T)来使用。

一个解决方案可以是显性的,如下面的简单示例

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

但我明白,显性化int(*)(std::tuple<int>)是在屁股大的痛苦。

你可以简化一点使用事实,你通过t所以你可以推断函数接收的参数的类型,但(对于通用的解决方案)我不知道如何避免显式的返回类型功能(也许是可能的,但(在这个时刻)我不知道。

因此可以简化通话如下

apply<int>(add_pointer, t_i); 

和下面是一个小更一般的例子

#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

谢谢你的帮助,但它真的不是我执行后的实现,我使用我自己的元组一个类型元组没有值,然后我传递一个模板函数或变量,然后用类型的元组中的所有不同类型进行评估。 –