2017-06-06 59 views
1

下面是一个例子 “实用C++元编程”(16/17页)C函数的参数:提取(从 “实用C++元编程” 实施例)使用C++元编程

#include <tuple> 
#include <typeinfo> 

template <typename F> 
struct make_tuple_of_params; 

template <typename Ret, typename... Args> 
struct make_tuple_of_params<Ret (Args...)> 
{ 
    using type = std::tuple<Args...>; 
}; 

template <typename F> 
using make_tuple_of_params_t = typename make_tuple_of_params<F>::type; 

template<typename F> 
void some_magic_function(F f) 
{ 
    // if F is in the form void(double*, double*) 
    // make_tuple_of_params is std::tuple<double*, double*> 
    make_tuple_of_params_t<F> params; 

    // ... 
} 

void Foo(double* x, double* y) { } 

int main() 
{ 
    some_magic_function(Foo); 
} 

它未能编译:

$ clang++ -std=c++14 MakeTuple.cpp 
MakeTuple.cpp:14:5: error: implicit instantiation of undefined template 'make_tuple_of_params<void (*)(double *, double*)>' 

这是因为没有定义make_tuple_of_params(上面代码的第4行和第5行)的非专用版本?

回答

3

您实际上需要不同的重载,具体取决于您是从指针还是从签名模板参数中提取它,请参见下文。

template <typename F> 
struct make_tuple_of_params; 

template <typename Ret, typename... Args> 
struct make_tuple_of_params<Ret (*)(Args...)> { 
    using type = std::tuple<Args...>; 
}; 

template <typename Ret, typename... Args> 
struct make_tuple_of_params<Ret(Args...)> { 
    using type = std::tuple<Args...>; 
}; 

template <typename F> 
using make_tuple_of_params_t = typename make_tuple_of_params<F>::type; 

template <typename F> 
bool some_magic_function(F f) { 
    // if F is in the form void(double*, double*) 
    // make_tuple_of_params is std::tuple<double*, double*> 
    return std::is_same<std::tuple<double*, double*>, make_tuple_of_params_t<F>>::value; 
} 

void Foo(double* x, double* y) {} 

int main() { 
    cerr << some_magic_function(Foo) << endl; 
    cerr 
    << std::is_same<std::tuple<int, int>, make_tuple_of_params_t<void(int, int)>>::value 
    << endl; 
    // The latter one might be handy in some of template metaprogramming constructs 
    return 0; 
} 

对不起,没有看书页,所以不知道那里的authro是什么意思。

+0

谢谢 - 感谢您的回答。 – AlphaBetaKilo