#c #c 17 #typetraits
#c #c 17 #typetraits
Вопрос:
Позвольте мне проиллюстрировать. Давайте возьмем, например, std::is_same_v и std::is_base_of_v. Рассмотрим следующий код:
#include <iostream>
#include <array>
#include <type_traits>
using namespace std;
struct base {};
struct derived : base { int foo; };
array<derived, 10> my_array;
int main()
{
using c1 = decltype(*begin(my_array));
using c2 = derived;
if constexpr(is_same_v<c1,c2>)
{
cout<<"Correct!"<<endl;
}
else
{
cout << "No luck even though:" << endl
<< "c1 type is " << typeid(c1).name() << endl
<< "c2 type is " << typeid(c2).name() << endl;
}
if constexpr(is_base_of_v<base, c1>)
{
cout<<"Correct!"<<endl;
}
else
{
cout << "No luck even though:" << endl
<< "is_base_of_v<base, derived> = " << is_base_of_v<base, derived> << endl;
}
return 0;
}
Ожидаемый результат:
Correct!
Correct!
Но фактический результат как в clang 10, так и в gcc 11:
No luck even though:
c1 type is 7derived
c2 type is 7derived
No luck even though:
is_base_of_v<base, derived> = 1
Взорванный разум. В первую очередь меня интересует выяснить точную причину такого поведения, а затем, возможно, найти обходной путь. Если возможно, обходной путь должен работать с любым итеративным типом и только с std::array .
Комментарии:
1. Это было так. Пожалуйста, отправьте это как ответ, чтобы я пометил его как правильный. Меня сбило с толку то, что typeid сообщал о том же типе. Спасибо.
Ответ №1:
Ваша проблема в том, что у вас есть дополнительная ссылка:
using c1 = decltype(*begin(my_array)); // derivedamp;
using c2 = derived;
is_same_v<derived, derivedamp;>
равно false .
std::decay_t
или std::remove_reference_t
может помочь.
И typeid идентичны:
- Ссылается на объект std::type_info, представляющий тип type . Если type является ссылочным типом, результат ссылается на объект std::type_info, представляющий ссылочный тип.
Другой способ узнать тип — использовать этот трюк:
template <typename> struct Debug; /*No definition*/
Debug<c1> d; // Incomplete type
с сообщением об ошибке, похожим на
ошибка: агрегат «
Debug<derivedamp;> d
имеет неполный тип и не может быть определен