有条件地在c ++中强制执行模板类型

Dor*_*ori 6 c++ templates

我有一个类模板,需要能够通过从Compare我拥有的类派生的比较对象来比较两个对象:

template<typename T>
class Container {
public:
    template<typename A, typename B>
    class Compare {
    public:
        virtual bool eq(const A&, const B&) const = 0;
    };
Run Code Online (Sandbox Code Playgroud)

我提供了一个默认的比较对象,假设type T有运算符==:

    template<typename A, typename B>
    class Default : public Compare<A,B> {
    public:
        bool eq(const A& a, const B& b) const { return a==b; }
    };
private:
    Compare<T,T>* comparison_object;
    bool uses_default;
    Container() : comparison_object(new Default<T,T>()), uses_default(true) {}
    Container(Compare<T,T>& cmp) : comparison_object(&cmp), uses_default(false) {}
    ~Container() { if(uses_default) delete comparison_object; }
};
Run Code Online (Sandbox Code Playgroud)

然而,当我尝试与自定义类编译此具有operator==过载(即使我提供了从派生的对象Compare):

MyObjCmp moc;
Container<MyObj>(&moc);
Run Code Online (Sandbox Code Playgroud)

编译器抱怨运算符不存在:

error: no match for 'operator==' (operand types are 'const MyObj' and 'const MyObj')
Run Code Online (Sandbox Code Playgroud)

这是有道理的,因为Default即使我不需要它,仍然需要创建类.但现在我需要一个解决方法......

有任何想法吗?

Mik*_*our 4

您可以对没有对象使用编译时检查,而不是对空指针进行运行时检查:

Container() : comparison_object(new Default<T,T>), uses_default(true) {}
Container(Compare<T,T>& cmp) : comparison_object(&cmp), uses_default(false) {}
Run Code Online (Sandbox Code Playgroud)

默认构造函数,因此Default只有在需要时才会被实例化,因此当使用具有失败类型的非默认构造函数时,不会出现错误Default

但要小心地处理这样的原始指针,这会导致内存泄漏甚至更糟。不要忘记虚拟析构函数Compare三规则,并且要非常小心非默认比较器不会被意外破坏。更好的是,使用智能指针来为您处理所有这些事情。