@iihaarr

Как с помощью шаблонов проверить, что два числа равны?

Я пытался так:
template<typename R, typename C, typename std::enable_if<std::is_arithmetic<R>::value && std::is_arithmetic<C>::value>::type = true>
struct are_values_equal
{
    constexpr static bool value = R == C;
};

И так:
template<const std::size_t R, const std::size_t C>
struct are_values_equal
{
    constexpr static bool value = R == C;
};

Но в первом в случае я так понимаю, что компилятор не может понять, что сравниваются два числа, а во втором ошибка:
a non-type template parameter cannot have type
В обоих случаях передаю 2 шаблонных параметра типа const std::size_t.
  • Вопрос задан
  • 85 просмотров
Пригласить эксперта
Ответы на вопрос 1
wataru
@wataru Куратор тега C++
Разработчик на С++, экс-олимпиадник.
Отвечаю на вопрос из комментариев. Можно сделать так:

template <int a, int b>
class A {
    public:
    template<bool tmp = true>
    typename std::enable_if<a==b && tmp, int>::type F() {
       return 1;   
    }
};

...

A<1,1> a;
std::cout << a.F();  // OK.
A<2,100> b;
std::cout << b.F(); // Ошибка A<2,100> не имеет метода F().


Мне сложно объяснить, чтобы было понятно, почему работает именно это, но я попробую.

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

Далее, хотелось бы что бы просто работало вот это:
template<>
 typename std::enable_if<a==b, int>::type F()

Тут все понятно, enable_if не имеет type, если a неравно b. Шаблон никак не инстанциировать и метод не должен был бы генерироваться. Но это было бы слишком просто.

Вместо этого, надо там завести какой-то вообще ненужный как бы параметр шаблона tmp, и обязательно использовать его в enable_if. Это потому что если в этом шаблоне не будет никак использоваться параметр шаблона, то SFINAE не срабатывает, и вылезает ошибка компиляции.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы