以下是" 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行)吗?
答案 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的意思。