c++ - 为模板重载函数模板班级
问题描述
我不明白为什么这不能编译,你能给我一个简短的理由吗?
template <typename... Args>
class Signal{};
template <template <typename... SignalArgs> class Signal, typename... Args>
void f(Signal<SignalArgs...>&& signal, Args&&... args)
{}
gcc 提供的错误是:
error: 'SignalArgs' was not declared in this scope; did you mean 'Signal'?
11 | void f(Signal<SignalArgs...>&& signal, Args&&... args)
| ^~~~~~~~~~
| Signal
<source>:11:25: error: expected parameter pack before '...'
11 | void f(Signal<SignalArgs...>&& signal, Args&&... args)
| ^~~
<source>:11:28: error: template argument 1 is invalid
11 | void f(Signal<SignalArgs...>&& signal, Args&&... args)
|
更重要的是,编写这种重载的正确方法是什么?请注意,我需要两种变体f
- 一种是有问题的,另一种是template <typename F> void f(F&&);
我绝对不希望 的任何实例Signal
,包括Signal<>
,进入泛型重载。
在 Godbolt 上在线试用:https ://godbolt.org/z/Xawz6G
解决方案
问题是SignalArgs
没有声明函数模板的参数。它只是一个标识符,可以选择出现在声明实际模板参数的声明器中,即Signal
. 它与声明函数类型的声明器中的函数参数名称基本相同,例如:
void f(void(*fp)(int a, int b))
{}
这里,f
是一个函数,它接受一个参数,该参数fp
是一个指向一个函数的指针,该函数接受两个类型的参数int
。标识符a
和b
是冗余的,与SignalArgs
原始示例中的方式相同。它们可能会出现,但它们并没有真正起到任何作用。
由于SignalArgs
不是您的函数模板的模板参数,因此无法推导出它(模板参数推导只涉及推导函数模板参数的参数)。做您想做的事情的方法是引入一个单独的模板参数,该模板参数用于您的函数参数的类型,signal
以便可以推断:
template <template <typename...> class Signal, typename... SignalArgs, typename... Args>
void f(Signal<SignalArgs...>&& signal, Args&&... args)
{}
这里的工作示例
推荐阅读
- javascript - 通过将 url 与 JQuery 交替更改嵌入 twitter
- python - 推文后硒找不到按钮
- angular - 使用 ngx-translate 在 Ionic/Angular 应用程序中设置语言时遇到问题
- node.js - React mongoose 验证失败
- c# - 为什么重新启动会清除“找不到类”错误?
- ajax - Larave/Ajax PUT 500 internal server error 可能的原因
- python - 使用 IB API 请求市场数据一次可以工作一次 python
- go - 去结构初始化
- .net - SignalR 的响应中的 C 值是什么意思?
- sql - 分母中的Count(*) -1 - sql