std :: is_floating_point возвращает false для float в некоторых случаях
В некоторых случаях, см. Один пример ниже, std::is_floating_point
возвращает false
для 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++?
FYI, я проверил как с GCC, так и с VisualStudio. В этом примере я использовал std :: vector, но можно также попробовать другие библиотеки, такие как Eigen.
Ответы
Ответ 1
Нет ошибки, и std::is_floating_point
дает вам правильный ответ.
vector<float>[n]
не дает вам float
; он дает вам float&
.
typeid
игнорирует это для удобства, но, поскольку более "мощные" инструменты, decltype
и std::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
любом случае вам не нужен 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