Вот минимальный пример:
struct incomplete_type;
template<typename T>
struct foo
{
using type = std::conditional_t<std::is_arithmetic_v<T>,
std::conditional_t<sizeof(T) < sizeof(void*), int, float>,
double>;
};
foo<incomplete_type> f;
вызовет ошибку, потому что он будет делать sizeof с типом, даже если incomplete_type
не является арифметическим типом (т. Е. Он не будет входить вразмер ветки логично). live demo
Итак, я хочу отложить sizeof
:
первая попытка (сбой)
template<typename T>
auto
foo_aux()
{
if(sizeof(T) < sizeof(T*))
return 0;
else
return 0.0f;
}
conditional_t<std::is_arithmetic_v<T>, decltype(foo_aux<T>()), double>
все еще вызывает ту же ошибку.
вторая попытка (ошибка)
template<typename T, bool>
struct foo_aux_aux
{
using type = float;
};
template<typename T>
struct foo_aux_aux<T, true>
{
using type = int;
};
template<typename T, bool = false>
struct foo_aux : foo_aux_aux<T, sizeof(T) < sizeof(void*)>
{};
conditional_t<std::is_arithmetic_v<T>, typename foo_aux<T>::type, double>
все еще вызывает ту же ошибку.
третья попытка (успех)
template<typename T, bool comp>
struct foo_aux_aux
{
using type = float;
};
template<typename T>
struct foo_aux_aux<T, true>
{
using type = int;
};
template<typename T, bool isArithmeticType>
struct foo_aux
{
using type = double;
};
template<typename T>
struct foo_aux<T, true>
{
using type = typename foo_aux_aux<T, sizeof(T) < sizeof(void*)>::type;
};
Да, это работает, как ожидалось , но это действительно утомительно и безобразно.
У вас есть элегантный способ здесь?