Специализация вложенного шаблона в классе шаблона после его объявления - PullRequest
0 голосов
/ 01 июля 2019

У меня есть определение моего собственного типа bool

template<bool b>
struct Bool {
    constexpr static bool value = b;
};

using True = Bool<true>;
using False = Bool<false>;

Я пытаюсь получить что-то вроде экземпляра haskell Bool класса Eq.

template<typename T>
struct Eq {
    template<typename R>
    struct equal;

    template<typename R>
    struct notEqual {
        using value = typename not_<typename equal<T, R>::value>::value;
    };
};

Интересно, как это сделать?специализация класса "равный".Чтобы быть более понятным, я хочу что-то вроде этого:

template<bool a>
template<bool b>
struct Eq<Bool<a>>::equal<Bool<b>> {
    using value = typename std::conditional<a == b, True, False>::type;
};

Есть ли решение для этого?Я попытался сделать этот трюк:

template<bool a>
struct Eq<Bool<a>>::equal<Bool<a>> {
    using value = True;
};

, но компилятор говорит мне: «mtp::Eq<T>::equal: слишком много аргументов шаблона».Спасибо за вашу помощь.

Ответы [ 2 ]

0 голосов
/ 01 июля 2019

Если вы хотите частично специализироваться Eq<Bool<a>>::equal<Bool<b>>, вам нужно сделать это в нескольких частях:

template <bool b>
struct Eq<Bool<b>> {
    template<typename R>
    struct equal;

    template<typename R>
    struct notEqual {
        using value = typename not_<typename equal<T, R>::value>::value;
    };
};

тогда

template<bool a>
template<bool b>
struct Eq<Bool<a>>::equal<Bool<b>> {
    using value = typename std::conditional<a == b, True, False>::type;
};

Демо

0 голосов
/ 01 июля 2019

Вы не можете специализироваться на зависимом шаблоне, таком как Bool<a>. Будет работать следующее:

template<typename T>
template<bool b>
struct Eq<T>::equal<Bool<b>> {
    using value = /* ... */;
};

Вы можете использовать std::enable_if_t, чтобы убедиться, что T является Bool, и использовать другой шаблон для извлечения значения этого типа Bool.

живой пример на Годболте

...