在某些情况下,std :: is_floating_point为float返回false

Clè*_*lèm 15 c++ floating-point types std typeid

在某些情况下,请参见下面一个例子,std::is_floating_point在返回falsefloat.

#include <iostream>
#include <type_traits>
#include <vector>

int main()
{
    ::std::cout << typeid(decltype(::std::vector< float >()[::std::vector< float >().size()])).name() << ::std::endl;
    if (::std::is_floating_point< decltype(::std::vector< float >()[::std::vector< float >().size()]) >::value)
    {
        ::std::cout << "floating point" << ::std::endl;
    }
    else
    {
        ::std::cout << "not floating point" << ::std::endl;
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

GCC的输出

f
not floating point
Run Code Online (Sandbox Code Playgroud)

在这个例子中,人们可以看到它typeid::std::vector< float >()[::std::vector< float >().size()]视为a float,它返回正确的名称.人们也可以检查typeid(decltype(::std::vector< float >()[::std::vector< float >().size()])) == typeid(flat)退货true.但是,std::is_floating_point返回假.为什么?这是C++的错误吗?

仅供参考,我与GCC和VisualStudio进行了核实.在这个例子中,我使用了std :: vector,但也可以尝试使用其他库,例如Eigen.

Lig*_*ica 30

没有错误,并std::is_floating_point给你正确的答案.

vector<float>[n]不给你一个float; 它给你一个float&.

typeid忽略这一点是为了方便,但是,作为更"强大"的工具,decltypestd::is_floating_point不是.

你可以std::remove_reference用来解决这个问题:

if (::std::is_floating_point_v<std::remove_reference_t<
   decltype(::std::vector< float >()[::std::vector< float >().size()])
>>)
Run Code Online (Sandbox Code Playgroud)

你也可以考虑一下std::decay.

你不需要decltype,因为容器有这样的时间的方便类型别名.

这是我要做的:

#include <iostream>
#include <type_traits>
#include <vector>

int main()
{
    using V = std::vector<float>;

    ::std::cout << typeid(V::value_type).name() << '\n';
    if (::std::is_floating_point_v<V::value_type>)
        ::std::cout << "floating point\n";
    else
        ::std::cout << "not floating point\n";
}

// Output:
//   f
//   floating point
Run Code Online (Sandbox Code Playgroud)

现场演示

  • @Fred你不需要`main`中的`return`,就像现场演示所示,我故意将它删除,因为它没有意义.(还是)感谢你的建议. (2认同)
  • IMO,从'main()`中省略`return`仍然是不好的风格,我得到的印象是语言只允许它被允许,因为很多人都在使用这种糟糕的风格,并且由于某些原因它想让它们合法化. (2认同)
  • @Arne:我认为你是对的.我尽可能地试图忽略这些规则,因为它们让我头痛,从某种意义上看起来似乎是如此神秘;)虽然它们的构造是为了在这样的精确情况下产生"预期的"结果,所以当然有逻辑 (2认同)