C++ 基于模板变量参数的类模板内的函数指针定义 使用FuncDef=void(int a,int b); 模板 类错误函数{ 公众: void F1(R(*Fn)(Args…){}//错误:C2091函数返回函数 }; 模板类函数; 模板 类函数{ 公众: 空F1(R(*Fn)(Args…){} }; 无效测试(){ 错误函数errfunc;//触发上述编译错误 函数func;//没问题 }
(1) 为什么函数工作但函数不工作(检查注释中的编译错误)?背后的理论是什么(例如,CPPPreference中包含了关于C++的所有细节)C++ 基于模板变量参数的类模板内的函数指针定义 使用FuncDef=void(int a,int b); 模板 类错误函数{ 公众: void F1(R(*Fn)(Args…){}//错误:C2091函数返回函数 }; 模板类函数; 模板 类函数{ 公众: 空F1(R(*Fn)(Args…){} }; 无效测试(){ 错误函数errfunc;//触发上述编译错误 函数func;//没问题 },c++,templates,C++,Templates,(1) 为什么函数工作但函数不工作(检查注释中的编译错误)?背后的理论是什么(例如,CPPPreference中包含了关于C++的所有细节) (2) (可选)是否有一种方法可以使错误的函数工作,但不能以函数的形式工作?下面的类模板: 仅提供一个模板参数,该参数与类模板的第一个模板参数匹配: FuncDef用作errowfunction中R的参数 然而,您没有为模板参数包提供任何参数 因此,编译器的错误消息很能说明问题:您正在使用为模板参数R提供的模板参数实例化ErrorFunction类模板
(2) (可选)是否有一种方法可以使错误的函数工作,但不能以函数的形式工作?下面的类模板: 仅提供一个模板参数,该参数与类模板的第一个模板参数匹配:
用作FuncDef
中errowfunction
的参数R
R
提供的模板参数实例化ErrorFunction
类模板,该参数在语义上表示返回类型,但使用函数类型参数。也就是说,在相关的专门化中,R
是一种函数类型
WrongFunction<FuncDef> errfunc;
对于可选问题:使其
无效错误函数::F1(R*Fn)
@tedlynmo任何试图“修复”错误函数
(以一种不仅仅是使其成为函数
)的方式)都可能导致混淆,因为它的模板参数API一开始就没有构造,再加上这样一个事实(即使假定F1
成为静态成员)当在类模板的成员函数中用作函数参数时,类模板的模板参数处于非推导上下文中(不包括某些CTAD/ctor细节)。专门化在这里是一种很好的方法,但是函数
:s主模板的类型模板参数同样可以制作。。。。。。转换为非类型模板参数(在主模板中设置为auto
),因为函数指针是非类型模板参数的有效参数。您可能完全正确。我回答了可选问题-但该修复很可能没有得到建议。@TedLyngmo我用完全不同的内容进行了扩展,但仍然解决了可选问题代码>解决该问题。
template <typename R, typename... Args>
class WrongFunction {
public:
void F1(R(*Fn)(Args...)) {}//error: C2091 function returns function
};
WrongFunction<FuncDef> errfunc;
void F1(R(*Fn)(Args...)) {}
// resolves to, for WrongFunction<FuncDef> specialization
void F1( (void)(*)(int, int) (*Fn)() ) {}
// ^^^^^^^^^^^^^^^^^^^ <- R
#include <utility>
template <auto> class Function;
template <typename R, typename... Args, R (*Fn)(Args...)>
class Function<Fn> {
public:
template <typename... FnArgs /* optionally SFINAE that FnArgs is Args */>
void F1(FnArgs &&... args) {
Fn(std::forward<FnArgs>(args)...);
}
};
void f(int a, int b) {}
int main() {
Function<f> func;
func.F1(1, 2);
}