让我们想象一下,我在c ++中有类似haskell的类Maybe。例如,可以这样实现:
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>
或{{1} }我不需要了解有关T类型的任何信息。在haskell中,您可以使用下划线(<Nothing, Just<T>>
),但是c ++中有类似的东西吗?
答案 0 :(得分:0)
不知道您想要什么,但是...我想您想要的东西
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>
的{{1}}类型。
当类型名称是用于不同类型的T
类型,或者是Just
类型和Just
或两个Nothing
时,Nothing
专业化不会匹配,并且仅匹配主要版本(从JustEqual
继承)。
以这种方式观察,std::false_type
仅与主版本匹配,因此从JustEqual<Nothing, Nothing>
继承。我不清楚这是否是您想要的。
如果您希望std::false_type
继承自JustEqual<Nothing, Nothing>
,则可以添加特定的专业化名称
std::true_type
答案 1 :(得分:0)
我相信_
是模板参数的有效标识符,但是省略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;
};
答案 2 :(得分:0)
这不能回答您有关模板参数的通配符类型的问题。
针对您的特定问题,如果您用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;
};
。
p1.distanceTo(p2);