没有模板参数的抽象类的实现

时间:2016-04-14 13:52:33

标签: c++ inheritance abstract-class

我想实现两个简单的抽象类,如:

template <Hashable Key, typename Value>
class Dictionary {
     .
     .
     .
};

这些类将为我提供在新词典类中进行部分模板特化的机会。

然而,我无法让他们工作。这是我的词典类的声明:

Equatable

问题是,密钥也应该是Equatable<T>,因为可持续性应该需要它。

所以,我有两个问题:

  1. 我们可以重写Hashable类没有模板参数吗? C ++是否有任何关键字引用该类的当前类型?

  2. 在我看来,Equatable最好继承Hashable班级。如何在var markers = L.markerClusterGroup({ polygonOptions: { fillColor: '#1b2557', color: '#1b2557', weight: 0.5, opacity: 1, fillOpacity: 0.5 } }); 没有新的模板定义的情况下实现这一点(如果我的第一个问题回答是,那么这已经解决了)?

  3. 这里最好的面向对象方法是什么?使用模板参数的接口类看起来很俗气。

  4. 谢谢。

2 个答案:

答案 0 :(得分:2)

你基本上寻找的是概念,你可以用它来编写:

template <class T>
concept bool Hashable()
{
    return requires(T t, T u) {
        {t.hashValue()} -> size_t;
        {t == u} -> bool;
    };
}

template <Hashable Key, class Value>
class Dictionary {
    ...
};

但这甚至不会出现在C ++ 17中。

在此之前,我们可以使用void_t

在C ++ 14中编写此类内容
template <class...> using void_t = void;

template <class T, class = void>
struct Hashable : std::false_type { };

template <class T>
struct Hashable<T, void_t<
    std::enable_if_t<std::is_same<std::declval<T&>().hashValue(), std::size_t>::value>,
    decltype(std::declval<T&>() == std::declval<T&>())
    >>
: std::true_type { };

template <class Key, class Value>
class Dictionary {
    static_assert(Hashable<Key>::value, "Key must be Hashable<>");
    ...
};

请注意,在这两种情况下,我们都要求Key类型具有此功能 - 我们不要求Key 继承虚拟。这样效率更高。无需虚拟调度。

  

这里最好的面向对象方法是什么?

不使用面向对象的方法。

答案 1 :(得分:1)

我相信

template <Hashable Key, typename Value>

实际上并没有按照您的预期行事。考虑:

template <int Key, typename Value> class x{};

现在,您可以实例化x<1, int>x<2, int>,但这些不仅仅是不同的对象,而是不同的类型。因此,在您的情况下,您的Hashable对象将成为该类型的一部分(因此它必须在编译期间生成,而不是在运行时生成)。

你最想要的是 - 就像在另一个答案中提到的Wojciech Frohmberg:

template <typename K, typename V>
class Dict {
...
static_assert(std::is_base_of<K, Hashable>::value, "Only Hashable can be the key);
}

enable_iftype_traits中包含的其他模板魔法。

您正在寻找的是概念,甚至没有制作C ++ 17或类型类(在其他语言中可用,如Haskell或Scala)

如果您真的想在这里使用面向对象的方法,请选择以下内容:

template <typename Value> 
class Dict {
    Dict(std::shared_ptr<Hashable>, Value) 
    {}
}

但是,这不是典型的实现,所以我不推荐它