Условная специализация - PullRequest
0 голосов
/ 07 мая 2020

Предположим, у меня есть следующее:

template<std::size_t> struct s;
template<> struct s<sizeof(int)>  { /*...*/ };
template<> struct s<sizeof(long)> { /*...*/ }; // will not compile as it already exists.

Как мне реализовать проверку для условного различения двух экземпляров? Я хочу реализовать последнее только в том случае, если они не равны.

Очевидно, sizeof не является конструкцией, которая может быть оценена препроцессором. Какие у меня есть варианты?

Ответы [ 2 ]

1 голос
/ 07 мая 2020

Вы можете сделать так, чтобы обе специализации имели (неограниченный) std::size_t и включали специализацию, только если это == sizeof(int) или == sizeof(long) && sizeof(long) != sizeof(int):

#include <type_traits>
#include <cstddef>

template<std::size_t, typename = void> struct s;

template<std::size_t N>
struct s<N, std::enable_if_t<N == sizeof(int)>> { /* ... */ };

template<std::size_t N>
struct s<N, std::enable_if_t<N != sizeof(int) && N == sizeof(long)>> { /* ... */ };
0 голосов
/ 08 мая 2020

Если вы можете зарезервировать «недопустимое» значение, вы можете заменить его, чтобы избежать столкновения:

template<std::size_t> struct s;
template<> struct s<sizeof(int)> { /*...*/ };
template<> struct s<sizeof(long)==sizeof(int) ? -1 : sizeof(long)> { /*...*/ };

Также иногда можно использовать if constexpr вместо явных специализаций, так что дублирование не ошибка.

...