GCC拒绝传递函数指针至带const参数的可变参数模板函数的合规性问询
C++模板函数编译一致性问题分析
问题背景
一段C模板函数代码可被Clang、MSVC正常编译,但GCC会拒绝编译,现依据最新C标准判断各编译器行为是否合规。
代码示例
template<typename... T> double BigFunction(double (*func)(const T...), double var) { return {}; } double f3(double, int) { return {}; } int main() { BigFunction(f3, 3); // GCC编译失败,Clang、MSVC编译通过 }
GCC报错信息
<source>: In function 'int main()': <source>:15:16: error: no matching function for call to 'BigFunction(double (&)(double, int), int)' 15 | BigFunction(f3, 3);// GCC: no but Clang + MSVC: ok | ~~~~~~~~~~~^~~~~~~ • there is 1 candidate • candidate 1: 'template<class ... T> double BigFunction(double (*)(const T ...), double)' <source>:3:32: 3 | template<typename... T> double BigFunction(double (*func)(const T...), double var) | ^~~~~~~~~~~ • template argument deduction/substitution failed: • types 'const T' and 'double' have incompatible cv-qualifiers <source>:15:16: 15 | BigFunction(f3, 3);// GCC: no but Clang + MSVC: ok | ~~~~~~~~~~~^~~~~~~ ASM generation compiler returned: 1
标准依据与结论
根据C++标准,函数类型的参数中顶层const限定符会被忽略——也就是说,double(const double, const int)和double(double, int)属于完全相同的函数类型。
在模板参数推导阶段,当形参为double(*func)(const T...),实参是double(double, int)类型的函数时,T可被推导为double和int,此时形参对应的函数指针类型double(*)(const double, const int)与实参的函数指针类型本质等价,推导应当成功。
因此,Clang和MSVC的行为符合C++标准,GCC的报错不符合规范。
内容的提问来源于stack exchange,提问作者Anoop Rana
相关产品推荐
相关产品推荐

