我可以抽象出有关模板 类 的具体细节吗?

Can I abstract away specific details about templated classes?

我正在使用 C++11 创建一个工厂库(类似于 https://github.com/google/guice,可用于 Java),以熟悉模板编程,并创建一个有用的依赖减少工具。这个想法是工厂将抽象出对象的创建和销毁的细节,并隐藏实现细节。理想情况下,我想要类似的东西:

InterfaceClass
{
    public:
    virtual void doSomething () = 0;
    virtual ~InterfaceClass () {};
}

// Might need custom deleter depending on how the class was allocated
// (might come from a pool, etc)
ImplementationClass : public InterfaceClass
{
    public:
    // Some (possibly) complicated constructor.
    ImplementationClass(Dependency one, Other dependency) {}

    virtual void doSomething ()
    {
        // Implementation
    }

    virtual ~ImplementationClass ()
    {

    }
}

理想情况下,我希望图书馆的最终用户能够(或类似的东西):

std::unique_ptr<InterfaceClass> object = factory<InterfaceClass>();

如果所有 类 使用默认删除器,这会很好用,但在自定义删除器的情况下,unique_ptr 的类型从:

std::unique_ptr<I> 

至:

std::unique_ptr<I, deleter> 

-- 据我所知,这些类型不兼容。

有没有一种方法可以定义某种更高级别的 "unique pointer",它不关心类型签名中的删除器?保持 API 对对象的创建/删除不可知的其他可能的解决方法?

谢谢!

使用 std::function 获得通用的类型擦除删除器。

Ideone link

#include <iostream>
#include <memory>
#include <functional>

template<typename T>
using TypeErasedUPtr = std::unique_ptr<T, std::function<void(T*)>>;

int main() 
{
    TypeErasedUPtr<int> p1{new int(5), [](int* x){ delete x; }};
    TypeErasedUPtr<int> p2{someAllocator<int>(5), [](int* x){ someDeallocator(x); }};

    // `p1` and `p2` have the same type, `TypeErasedUPtr<int>`.

    return 0;
}

这是有效的,因为 std::unique_ptr<T, TDeleter> 接受任何可以用 T* 参数调用的可调用 TDeleter 类型。

一个 std::function<void(T*)> 满足了这个要求,并且还在 运行 时间以多态方式包装了具有该签名的任何类型的函数(通过支付小的 运行 时间开销价格)。

您始终可以包装需要自定义删除器的类型。实际上你 应该 这样做,因为自定义删除器是你不希望暴露给 public 的实现细节。