Различное определение функции-члена согласно условию времени компиляции

Согласно этому ответу, я использую

template <typename T,
          typename = typename enable_if<bool_verfier<T>()>::type> >
classMember(const T& arg);

В качестве сигнатуры функции для нескольких членов класса, где bool_verifier<T>() является шаблонной функцией, которая утверждает, что определенный класс T выполняет определенные требования, с типом возврата constexpr bool, Это обеспечивает особую перегрузку classMember(const T& arg) используется только для определенных типов аргументов, но это невозможно сделать при наличии нескольких перегрузок с одной и той же сигнатурой прототипа / аргумента, потому что компилятор не допустит этого:

// ...
template <typename T, typename = typename enable_if<bool_verfier<T>()>::type> >
classMember(const T& arg);
template <typename T,  typename = typename enable_if<!(bool_verfier<T>())>::type>>
classMember(const T& arg);
// ...

что приводит к следующей ошибке компиляции:

 ‘template<class T, class> void myClass::classMember<T>(const T&)’
 cannot be overloaded with
‘template<class T, class> void std::myClass<T>::classMember(const T&)’

Если мне нужно classMember иметь разные определения в зависимости от того, bool_verifier<T>() возвращает true, что будет правильным синтаксисом / объявлением члена? Альтернативно, есть ли способ позвонить bool_verifier<T> из #if условный оператор прекомпилятора?

1 ответ

Решение

Альтернативно, есть ли способ позвонить bool_verifier<T> из #if условный оператор прекомпилятора?

Нету. Препроцессор работает раньше всего на свете и совсем не знает C++.


Вы, вероятно, должны устранить неоднозначность между двумя перегрузками с помощью дополнительного параметра шаблона (или путем изменения где enable_if), поскольку значения параметров шаблона по умолчанию не являются частью подписи. Следующие работы для меня:

struct foo
{
     template <typename T, typename = std::enable_if_t<bool_verifier<T>{}>> 
     void a();

     template <typename T, typename = std::enable_if_t<!bool_verifier<T>{}>, typename = void> 
     void a();
};

прямая ссылка godbolt.org

Другие вопросы по тегам