Есть ли альтернатива подчеркиванию haskell в c ++? - PullRequest
0 голосов
/ 01 июля 2019

Давайте представим, что у меня есть класс, похожий на haskell. Может быть, в c ++. Например, это может быть реализовано так:

template<typename T, typename val> 
struct Maybe;

template<typename val> struct Maybe<std::true_type, val> {  
    using value = val; 
};

template<> struct Maybe<std::false_type, void> {

};

template<typename val> 
using Just = Maybe<std::true_type, val>;

using Nothing = Maybe<std::false_type, void>;

Я хочу сравнить их, используя функцию «равно»:

template<typename T, typename R>
struct equal;

Если у меня есть экземпляр <Just<T>, Just<R>>, мне нужны оба типа T и R, чтобы узнать результат сравнения, но в случае <Just<T>, Nothing> или <Nothing, Just<T>> мне не нужно ничего знать о тип T. В haskell вы можете использовать подчеркивание (Just _), но есть ли что-нибудь подобное в c ++?

Ответы [ 3 ]

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

Я полагаю, _ является допустимым идентификатором для параметра шаблона, но пропуск typename _ не позволит его распознать в качестве параметра шаблона. Итак, самое близкое, что вы можете получить, это:

template<typename T, typename R>
struct equal;

template<typename T, typename R>
struct equal<Just<T>, Just<R>> {
    using value = typename std::conditional<std::is_same<T, R>::value, True, False>::type;
};

template<typename _>
struct equal<Just<_>, Nothing> {
    using value = False;
};

template<typename _>
struct equal<Nothing, Just<_>> {
    using value = False;
};

template<>
struct equal<Nothing, Nothing> {
    using value = True;
};
0 голосов
/ 06 июля 2019

Это не отвечает на ваш вопрос о типе шаблона для параметров шаблона.

Рассматривая вашу конкретную проблему, вы можете упростить определение equal, если определите его в терминах Maybe вместо Just и Nothing. Важно то, что оба параметра Maybe будут одинаковыми, и поэтому это будет верно и для Nothing.

Это позволяет упростить определение equal, поскольку теперь он может по умолчанию False.

template<typename, typename>
struct equal {
    using value = False;
};

template<typename B, typename V>
struct equal<Maybe<B, V>, Maybe<B, V>> {
    using value = True;
};

Попробуйте онлайн!

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

Не уверен, что понимаю, что ты хочешь, но ... я полагаю, вы хотите что-то как

template <typename, typename>
struct JustEqual : public std::false_type
 { };

template <typename T>
struct JustEqual<Just<T>, Just<T>> : public std::true_type
 { };

Таким образом, JustEqual наследуется от std::true_type, если (если и только если) оба типа названий являются Just<T> типами для одного и того же T.

Если имя типа имеет тип Just для разных типов, или тип Just и Nothing, или два Nothing, специализация JustEqual не совпадает, а только основная версия (которая наследуется от std::false_type).

Заметьте, что таким образом, JustEqual<Nothing, Nothing> соответствует только основной версии, поэтому наследуйте от std::false_type. Мне не ясно, если это то, что вы хотите.

Если вы хотите, чтобы JustEqual<Nothing, Nothing> наследовали от std::true_type, вы можете добавить определенную специализацию

template <>
struct JustEqual<Nothing, Nothing> : public std::true_type
 { };
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...