首页 > 解决方案 > 使用 clang++ 和 g++ 的 enable_if 的不同行为

问题描述

当我编译以下代码时:

#include <boost/numeric/interval.hpp>
#include <complex>

int main(){
  std::complex<boost::numeric::interval<double> > my_interval(1,1);
  my_interval *= my_interval;
  return 0;}

使用

g++ -std=c++14 main.cpp

或者

clang++ -std=c++14 main.cpp   

我得到两种不同的行为。g++ 编译良好,而 clang++ 编译失败,因为调用

std::enable_if<std::is_arithmetic<_A1>::value, bool>::type

禁用某些必需的功能。有简单的解决方法吗?难道我做错了什么?

版本:

完整且完整的错误:

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/complex:599:9: error: 
  no matching function for call to 'isnan'
if (isnan(__x) && isnan(__y))
    ^~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/complex:312:27: note: 
  in instantiation of function template specialization
  'std::__1::operator*<boost::numeric::interval<double,
      boost::numeric::interval_lib::policies<boost::numeric::interval_lib::rounded_math<double>,
  boost::numeric::interval_lib::checking_strict<double> > > >' requested
  here
        *this = *this * complex(__c.real(), __c.imag());
                      ^
main.cpp:6:15: note: in instantiation of function template specialization
  'std::__1::complex<boost::numeric::interval<double,
  boost::numeric::interval_lib::policies<boost::numeric::interval_lib::rounded_math<double>,
  boost::numeric::interval_lib::checking_strict<double> > >
  >::operator*=<boost::numeric::interval<double,
      boost::numeric::interval_lib::policies<boost::numeric::interval_lib::rounded_math<double>,
  boost::numeric::interval_lib::checking_strict<double> > > >' requested
  here
  my_interval *= my_interval;
          ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/cmath:424:25: note: 
  candidate template ignored: disabled by 'enable_if' [with _A1 =
  boost::numeric::interval<double,
      boost::numeric::interval_lib::policies<boost::numeric::interval_lib::rounded_math<double>,
  boost::numeric::interval_lib::checking_strict<double> > >]
  typename std::enable_if<std::is_arithmetic<_A1>::value, bool>::type

标签: boostg++clang++

解决方案


看起来 Boost.Numeric Interval 代码取决于不可移植的行为——准确地说,是调用isnan非算术类型的能力。

中的例程<cmath>只需要与算术类型一起使用,这些类型被定义为(广泛地)“内置整数和浮点类型”。

libstdc++ 在这里实现了扩展以支持其他类型,而 libc++ 没有。

棒球内部:标准的相关部分(和其他部分)

[稍后]:一个更基本的问题(导致我上面所说的)是使用std::__1::complex<boost::numeric::interval<double...>.

这也是不可移植的:[complex.numbers]/2 说:

为浮点、双精度或长双精度以外的任何类型实例化模板复合体的效果是未指定的。


推荐阅读