C++创建函数别名失败:变量模板类型推导出错
函数模板别名类型推导失败问题解决
尝试给std::fmax创建模板化的函数指针别名时,出现类型推导失败,但直接调用std::fmax<int>却能正常运行。
问题代码
#include <iostream> #include <cmath> template<class T> constexpr T (*max)(T, T) = std::fmax<T>; int main(){ double x = 6.28; double y = 4.45; std::cout << (max<int>(x, y)) << std::endl; }
编译器报错
<stdin>:6:28: error: address of overloaded function 'fmax' does not match required type 'int (int, int)' constexpr T (*max)(T, T) = std::fmax<T>;; ^~~~~~~~~~~~ <stdin>:14:16: note: in instantiation of variable template specialization 'max<int>' requested here std::cout << (max<int>(x, y)) << std::endl; ^ /data/user/0/ru.iiec.cxxdroid/files/bin/../lib/gcc/arm-linux-androideabi/4.9.x/../../../../include/c++/4.9.x/math.h:1200:1: note: candidate template ignored: failed template argument deduction fmax(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT ^
问题原因
std::fmax的模板签名是两个独立的模板参数(_A1和_A2),而非单个T。当你写std::fmax<T>时,只指定了第一个参数_A1=T,第二个参数_A2需要推导,但在给函数指针赋值时,编译器无法完成这个推导——函数指针要求精确匹配T(T,T)的签名,而std::fmax<T>此时是未完全特化的模板(签名为T(T, _A2)),没法直接转换成T(T,T)的函数指针。
而直接调用std::fmax<int>(x,y)时,编译器能通过实参x和y推导_A2=double,再隐式转换为int,所以能正常运行。
解决方法
方法1:用函数模板包装(推荐)
这种方式更灵活,还能支持不同类型的输入:
#include <iostream> #include <cmath> // 严格同类型输入的版本 template<class T> constexpr T max(T a, T b) { return std::fmax<T>(a, b); } // 支持不同类型输入,自动推导返回类型的版本 template<class T, class U> constexpr auto max(T a, U b) { return std::fmax(a, b); } int main(){ double x = 6.28; double y = 4.45; std::cout << max<int>(x, y) << std::endl; // 也可以用自动推导版本:std::cout << max(x, y) << std::endl; }
方法2:显式指定std::fmax的两个模板参数
如果一定要用函数指针变量模板,需要明确指定两个参数都为T:
#include <iostream> #include <cmath> template<class T> constexpr T (*max)(T, T) = std::fmax<T, T>; int main(){ double x = 6.28; double y = 4.45; std::cout << (max<int>(x, y)) << std::endl; }
内容的提问来源于stack exchange,提问作者JosephGen
相关产品推荐
相关产品推荐

