【问题标题】:Function pointer with templated parameter带模板参数的函数指针
【发布时间】:2017-04-22 15:48:57
【问题描述】:

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

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;
};

【问题讨论】:

  • 如果一切都按您的意愿运行,您能否展示一个示例用法?说明为什么虚拟析构函数不可行。
  • 请详细解释“不起作用”部分。你得到编译器错误吗?请张贴。
  • 我的意思是,函数指针不能指向模板。所以,是的,从最狭义的意义上说,“这个”是行不通的。如果你给我们更多的背景信息,我相信我们可以提出一个解决方案。

标签: c++ function templates pointers


【解决方案1】:

你不能有一个模板化的函数指针,仅仅因为函数模板的不同实例化是不同的函数并且不能都被同一个指针指向。

看看std::shared_ptr 很有启发性,巧合的是,它一个特定于类型的删除器回调。其工作方式是为特定类型创建删除器,而不是为任何类型创建。也就是说,shared_ptr&lt;Foo&gt; 有一个删除器,但它是Foos 的删除器,不能用于删除Bars。

除了实际编译之外,这还具有允许创建用于特定类型的删除器的优点。因此,在您的情况下,我建议您不要尝试更改 d 的类型;相反,您应该更改存储 d 的结构,以便它可以包含特定于类型的删除器而不是通用删除器。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-20
    • 2015-01-20
    • 2014-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多