Вроде содрал с примера на cppreference.com вариант #5 — " #5, enabled via a type template parameter", но не хочет компилякаться, говорит, что метод уже определён — member function already defined or declared
Хотел сделать, чтобы для целых типов и float работала базовая версия метода, для enum-ов — через std::underlying_type вызывалась та же версия, а для любого другого — чтобы не собиралось
Код примерно такой:
template< typename TMetaType, typename TRegType >
struct TypedIndex
{
typedef TMetaType MetaType;
size_t indexValue;
};
template< typename RegsData, typename RegsMeta >
class RegTable
{
public:
typedef RegsMeta meta_t;
template< typename TRegType >
using typed_index_t = TypedIndex< meta_t, TRegType >;
// Получение значения целочисленного или плавающего регистраtemplate< typename TRegType
// , typename std::enable_if< std::is_integral<TRegType>{}, bool>::type = true // #4, enabled via a non-type template parameter
, typename = std::enable_if< std::is_integral<TRegType>::value || std::is_floating_point<TRegType>::value >::type // #5, enabled via a type template parameter
>
void regGet( typed_index_t<TRegType> idx
, TRegType &val
)
{
//...
}
// Получение значения регистра типа enumtemplate< typename TRegType
//, typename std::enable_if< std::is_enum<TRegType>{}, bool>::type = true // #4, enabled via a non-type template parameter
, typename = std::enable_if< std::is_enum<TRegType>::value >::type // #5, enabled via a type template parameter
>
void regGet( typed_index_t<TRegType> idx
, TRegType &val
)
{
std::underlying_type<TRegType>::type tmp;
regGet(idx, tmp);
val = (TRegType)tmp;
}
};
У>Вроде содрал с примера на cppreference.com вариант #5 — " #5, enabled via a type template parameter", но не хочет компилякаться, говорит, что метод уже определён — member function already defined or declared
Под #5 вариантом сказано, что так и будет.
// #5, enabled via a type template parametertemplate<class T,
typename = std::enable_if_t<std::is_array<T>::value> >
void destroy(T* t) // note: function signature is unmodified
{
for(std::size_t i = 0; i < std::extent<T>::value; ++i) {
destroy((*t)[i]);
}
}
/*
template<class T,
typename = std::enable_if_t<std::is_void<T>::value> >
void destroy(T* t){} // error: has the same signature with #5
*/
Здравствуйте, σ, Вы писали:
У>>Вроде содрал с примера на cppreference.com вариант #5 — " #5, enabled via a type template parameter", но не хочет компилякаться, говорит, что метод уже определён — member function already defined or declared σ>Под #5 вариантом сказано, что так и будет. σ>А в https://en.cppreference.com/w/cpp/types/enable_if#Notes сказано как делать Right, а как Wrong. #5 — это Wrong.
Блин, продолбился в глаза Спс
Просто в самом первом примере RIGHT/WRONG написано до кода, а тут — после. И я что-то решил, что эта пометка относится к следующему кейсу
У> // , typename std::enable_if< std::is_integral<TRegType>{}, bool>::type = true // #4, enabled via a non-type template parameter
У> , typename = std::enable_if< std::is_integral<TRegType>::value || std::is_floating_point<TRegType>::value >::type // #5, enabled via a type template parameter
У>
По хорошему нужно использовать std::conjunction и std::disjunction вместо простой операций && или ||.
Они позволяют не вычислять правую часть при соблюдении условия левой части, что может быть критичным если у правой части есть условия когда она не будет компилироваться.
Кстати, в концептах как раз && и || означают именно std::conjunction и std::disjunction.
Здравствуйте, reversecode, Вы писали:
R>переходите на concept, писанины меньше, за одно будет чем перед пацанами по хвастать что вы уже используете 20 стандарт
Полностью поддерживаю.
Код стал гораздо проще в поддержке чем нагромождение enable_if-ов.
Здравствуйте, _NN_, Вы писали:
_NN>По хорошему нужно использовать std::conjunction и std::disjunction вместо простой операций && или ||. _NN>Они позволяют не вычислять правую часть при соблюдении условия левой части, что может быть критичным если у правой части есть условия когда она не будет компилироваться.
_NN>>По хорошему нужно использовать std::conjunction и std::disjunction вместо простой операций && или ||. _NN>>Они позволяют не вычислять правую часть при соблюдении условия левой части, что может быть критичным если у правой части есть условия когда она не будет компилироваться.
У>А операторы && или || разве не так работают?
Под "не вычислять" подразумевается "не инстанциировать".