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

时间:2018-09-12 09:03:01

标签: c++ types floating-point std typeid

在某些情况下,请参见下面的示例,std::is_floating_pointfalse返回了float

#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;
}

GCC的输出

f
not floating point

在此示例中,可以看到typeid::std::vector< float >()[::std::vector< float >().size()]视为float,因为它返回了正确的名称。也可以检查typeid(decltype(::std::vector< float >()[::std::vector< float >().size()])) == typeid(flat)返回true。但是,std::is_floating_point返回false。为什么?那是C ++的错误吗?

仅供参考,我同时检查了GCC和VisualStudio。在此示例中,我使用了std :: vector,但也可以尝试使用其他库,例如Eigen。

1 个答案:

答案 0 :(得分:30)

没有错误,std::is_floating_point为您提供了正确的答案。

vector<float>[n]没有给您floatit gives you a float&

typeid ignores this为方便起见,但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()])
>>)

您还可以考虑使用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

Live demo