使用C ++元编程提取C函数的参数(例如"实用C ++元编程")

时间:2017-06-06 16:25:05

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

以下是" Practical C ++ Metaprogramming" (第16/17页):

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

它未能编译:

public function get_login()
  {
    try {
      $redirect_uri = CustomAuthentication::process(
        $_GET['token'],
        $_GET['state'],
        $_GET['redirect_uri']
      );
      return Redirect::to($redirect_uri);
    } catch (\Exception $e) {
        $redirect_uri = $_GET['redirect_uri'] . '&' . http_build_query([
            'error' =>  $e->getMessage(),
            'state' => 401,
            'code' => $e->getCode(),
        ]);
        return Redirect::to($redirect_uri);
    }
  }

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

1 个答案:

答案 0 :(得分:4)

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

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的意思。