症状

g++ 5.3.0上编译用到Boost.Math的代码,对boost/math/constants/constants.hpp报 unable to find numeric literal operator 'operator""Q' 错误。提供的建议是 "use -std=gnu++11 or -fext-numeric-literals to enable more build-in suffixes",但用这些编译参数仍得到这个编译错误。

解法

如果不需要float128支持,正确解法是,给项目加个BOOST_MATH_DISABLE_FLOAT128的宏定义。
如果需要float128支持,建议换编译器到gcc7以上版本。

解说

operator""是C++11引入的User-defined literals语法,详见参考文献2。概括来说,就是允许在常量后面加个后缀来表示比较复杂的数据含义。
在Boost.Math代码中,不精确地说,operator""Qboost::multiprecision::float128的User-defined literals。参考文献1说gcc5、gcc6存在bug,对这段代码编译存在问题,所以建议升级到gcc7。
如果编译器不能换,那么要用别的方法。报错的代码行是用BOOST_DEFINE_MATH_CONSTANT宏定义常数的一行,这个漫长的定义里有一处BOOST_MATH_FLOAT128_CONSTANT_OVERLOAD,在有BOOST_MATH_USE_FLOAT128宏定义的情况下,BOOST_MATH_FLOAT128_CONSTANT_OVERLOAD里用BOOST_JOIN(x, Q)在某个表示数值的字符串后面拼了一个字母Q,显然这就是引起问题的地方。所以要设法关掉BOOST_MATH_USE_FLOAT128。根据Boost文档,以及boost/math/tools/config.hpp中相关代码,可以用BOOST_MATH_DISABLE_FLOAT128宏定义来禁止BOOST_MATH_USE_FLOAT128

参考资料

  1. SIENTIST. error: unable to find numeric literal operator ‘operator""Q’ 报错问题解决 [EB/OL]. https://www.jianshu.com/p/3cad27ca67eb
  2. cppreference.com . User-defined literals [EB/OL]. https://en.cppreference.com/w/cpp/language/user_literal