从自动模板参数回调中提取参数

Mar*_*tto 3 c++ template-meta-programming c++17

我试图从作为模板参数给出的回调推断出回调函数参数.我已经找到了前面的答案:你能从模板参数函数签名中提取类型,它看起来像是答案,但不知怎的,我不能让它为我想要的东西工作.

我有以下代码:

#include <tuple>

template<typename S>
struct signature;

template<typename R, typename... Args>
struct signature<R(Args...)>
{
    using return_type = R;
    using argument_type = std::tuple<Args...>;
};

template <auto callback>
void check_callback()
{
    using callback_type = decltype(callback);
    using arg1          = std::tuple_element_t<0, signature<callback_type>::argument_type>;
}

int main()
{
}
Run Code Online (Sandbox Code Playgroud)

当使用clang 6.0作为c ++ 17编译时,我收到以下错误:

错误:模板类型参数的模板参数必须是类型; 你忘了'typename'了吗?

如果我将定义callback_type的行更改为类似的行

using callback_type = void(int);
Run Code Online (Sandbox Code Playgroud)

然后它突然工作,所以给定一个有效的函数签名代码似乎工作.在对来自模板参数的函数使用decltype时,为什么它不起作用?

son*_*yao 5

在对来自模板参数的函数使用decltype时,为什么它不起作用?

因为在这种情况下callback_type是依赖名称,这取决于模板参数callback.然后你必须使用关键字typename.

在声明或模板定义中,typename可用于声明依赖名称是一种类型.

所以将代码更改为

using arg1 = std::tuple_element_t<0, typename signature<callback_type>::argument_type>;
//                                   ^^^^^^^^
Run Code Online (Sandbox Code Playgroud)

using callback_type = void(int);没有这样的问题; callback_type是一个独立的名字.