【问题标题】:Extracting C Function's Parameters Using C++ Metaprogramming (Example from "Practical C++ Metaprogramming")使用 C++ 元编程提取 C 函数的参数(示例来自“实用 C++ 元编程”)
【发布时间】:2017-06-06 16:25:05
【问题描述】:

以下是“实用 C++ 元编程”(第 16/17 页)的示例:

#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 行)没有定义吗?

【问题讨论】:

    标签: c++ metaprogramming template-meta-programming


    【解决方案1】:

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

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

    抱歉,没有看书页,所以不知道作者的意思。

    【讨论】:

    • 谢谢您的回答。
    猜你喜欢
    • 2017-04-13
    • 1970-01-01
    • 1970-01-01
    • 2017-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-07
    • 2020-09-06
    相关资源
    最近更新 更多