具有模板化参数的函数指针

时间:2017-04-22 15:48:57

标签: c++ function templates pointers

现在我有一个智能指针的类模板,它有一个成员函数指针,因为当使用基函数类型声明类时,我需要调用派生类的析构函数。 函数指针由:

声明
void (*d)(const void*);

定义者:

template<typename T> void DefaultDeleter(const void *p) { delete static_cast<T*>(const_cast<void*>(p)); }

初始化为:

d = &DefaultDeleter<U>;

跟:

d(static_cast<const void*>(px));

我想改变它,所以我不必继续施放指针因为我认为它可能会弄乱一些东西。我想将定义更改为:

template<typename T> void DefaultDeleter(T *p) { delete p; }

将由以下声明:

template<typename U> void (*d)(U*);
但是,这并不起作用。有没有人对此有什么想法? 非常感谢提前!

使用这些类进行测试:

class Base1 {
    protected:
        Base1() : derived_destructor_called(false) {
            printf("Base1::Base1()\n");
        }
    private:
        Base1(const Base1 &); // Disallow.
        Base1 &operator=(const Base1 &); // Disallow.
    protected:
        ~Base1() {
            printf("Base1::~Base1()\n");
            assert(derived_destructor_called);
        }
    protected:
        bool derived_destructor_called;
};

class Derived : public Base1 {
        friend void basic_tests_1();
    private:
        Derived() {}
        Derived(const Derived &); // Disallow.
        Derived &operator=(const Derived &); // Disallow.
    public:
        ~Derived() {
            printf("Derived::~Derived()\n");
            derived_destructor_called = true;
        }
        int value;
};

但是,我得到了有关Derived_mi类的无效指针的内存错误,我想到的唯一原因就是在转换过程中发生的事情:

class Base2 {
    protected:
        Base2() : derived_destructor_called(false) {
            printf("Base2::Base2()\n");
        }
    private:
        Base2(const Base2 &); // Disallow.
        Base2 &operator=(const Base2 &); // Disallow.
    protected:
        ~Base2() {
            printf("Base2::~Base2()\n");
            assert(derived_destructor_called);
        }
    protected:
        bool derived_destructor_called;
};

class Derived_mi : public Base1, public Base2 {
        friend void basic_tests_1();
    private:
        Derived_mi() {}
        Derived_mi(const Derived_mi &); // Disallow.
        Derived_mi &operator=(const Derived_mi &); // Disallow.
    public:
        ~Derived_mi() {
            printf("Derived_mi::~Derived_mi()\n");
            Base1::derived_destructor_called = true;
            Base2::derived_destructor_called = true;
        }
        int value;
};

1 个答案:

答案 0 :(得分:1)

你不能有一个模板化的函数指针,只是因为函数模板的不同实例化是不同的函数而且不能用同一个指针指向它们。

查看std::shared_ptr是有益的,其中具有类型特定的删除器回调。有效的方法是为特定类型创建删除器,而不仅仅是任何类型。也就是说,shared_ptr<Foo>有一个删除者,但它是Foo的删除者,不能用于删除Bar

除了实际编译之外,还有一个优点,即允许创建可用于特定类型的删除器。所以在你的情况下,我建议你不要试图改变d的类型;相反,您应该更改d存储的结构,以便它可以保存特定于类型的删除器而不是通用删除器。