Как я могу иметь ограниченный шаблон оператора? - PullRequest
0 голосов
/ 20 сентября 2018

Я пытаюсь сделать мой класс конвертируемым в любой тип перечисления.

enum dst_1 { /*...*/ };
enum dst_2 { /*...*/ };
class src { /*...*/ };

src s;
dst_1 d1 = s;
dst_2 d2 = s;

Я не хочу вручную добавлять преобразования для каждого типа перечисления, поэтому следующее не являетсяприемлемое решение:

// OK, but tedious - you must consider each enum type
class src
{
public:
  operator dst_1() const { /*...*/ }
  operator dst_2() const { /*...*/ }
  // ...
};

Выполнение преобразования шаблона не работает для параметра шаблона не может быть выведено :

// NOT OK: T cannot be deduced
class src
{
public:
  template< typename T > using Enum = enable_if_t< is_enum_v< T >, T >;
  template< typename T > operator Enum< T >() const { /*...*/ }
};

Единственное решение Iможет найти это шаблон с переменным числом , но мне он не нравится, так как он заставляет пользователя указать перечисления, которые он планирует использовать:

// ALMOST OK, but still tedious - you must know in advance what enums will be used
src< dst_1, dst_2 > s;
dst_1 d1 = s;
dst_2 d2 = s;

Итак, есть лилучшее решение? В идеале я хотел бы написать:

src s;
dst_1 d1 = s;
dst_2 d2 = s;

1 Ответ

0 голосов
/ 20 сентября 2018

Если преобразование шаблона не работает, параметр шаблона не может быть выведен:

Он не может быть выведен так, как вы это сделали, потому что T не выводитсяконтекст здесь:

template< typename T > using Enum = enable_if_t< is_enum_v< T >, T >;

Это не может быть выведено так же, как это не может быть выведено T:

template <typename T> struct identity { using type = T; }

template <typename T> void foo(typename identity<T>::type);
foo(0); // nope

Правильный способ написания этого шаблона оператора:

template <typename T, std::enable_if_t<std::is_enum_v<T>, int> = 0>
operator T() const;

Или альтернативно:

template <typename T, std::enable_if_t<std::is_enum_v<T>, int> = 0> using Enum = T;
template <typename T> operator Enum<T>() const;

Обратите внимание, что псевдоним имеет , равный Tбольше ничего.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...