Ответ 1
decltype(ItemTemplate::traits)
const std::tuple<TraitBlock, TraitRock>
.
Итак, вы должны где-то обрабатывать квалификатор cv.
Почему у меня странный вывод для этого кода? Как правильно проверить тип?
#include <iostream>
#include <tuple>
#include <type_traits>
template<typename T> struct is_tuple : std::false_type {};
template<typename... Ts> struct is_tuple<std::tuple<Ts...>> : std::true_type {};
struct TraitBlock {
using BlockLocation = struct { std::uint64_t x, y, z; };
};
struct TraitRock {};
struct ItemTemplate{
static constexpr auto traits = std::make_tuple(
TraitBlock{},
TraitRock{}
);
};
int main(){
using A = std::tuple<char, int,double,char>;
std::cout << is_tuple<decltype(ItemTemplate::traits)>::value
<< is_tuple<decltype(std::make_tuple(
TraitBlock{},
TraitRock{}
))>::value
<< std::endl;
}
Я использую mingw64-gcc 7.2.0 с -std = С++ 17, я получил вывод "01", Почему у меня два выхода? Разве они не одного типа?
decltype(ItemTemplate::traits)
const std::tuple<TraitBlock, TraitRock>
.
Итак, вы должны где-то обрабатывать квалификатор cv.
Обратите внимание, что тип ItemTemplate::traits
(т.е. decltype(ItemTemplate::traits)
) равен const std::tuple<TraitBlock, TraitRock>
, который не соответствует указанному типу (т.е. std::tuple<Ts...>
) по специализации is_tuple
.
Вы можете удалить константу std:: remove_const, например
std::cout << is_tuple<std::remove_const_t<decltype(ItemTemplate::traits)>>::value;
или добавьте еще одну специализацию для const
(и может volatile
):
template<typename... Ts> struct is_tuple<std::tuple<Ts...>> : std::true_type {};
template<typename... Ts> struct is_tuple<const std::tuple<Ts...>> : std::true_type {};
template<typename... Ts> struct is_tuple<volatile std::tuple<Ts...>> : std::true_type {};
template<typename... Ts> struct is_tuple<const volatile std::tuple<Ts...>> : std::true_type {};
Вам нужно удалить все квалификаторы. Вместо того, чтобы делать все это самостоятельно, вы должны использовать std::decay_t
, который удаляет все квалификаторы для вас и отправляет ваши данные. Например,
template<typename T>
struct is_tuple_impl : std::false_type {};
template<typename... Ts>
struct is_tuple_impl<std::tuple<Ts...>> : std::true_type {};
template<typename T>
struct is_tuple : is_tuple_impl<std::decay_t<T>> {}