如何将类的静态方法作为 std::unique_ptr 的删除器传递?

空白

我一直在尝试传递一个跟随类的静态方法deleterunique_ptr但我无法弄清楚正确的语法。如果我刚刚开始使用unique_ptr.

#include <iostream>
#include <memory>


class Singleton {

public:

    static void deleter(Singleton* p) {
        delete p;
        std::cout << "In deleter\n" << std::endl;
    }

    static std::unique_ptr<Singleton, decltype(&Singleton::deleter)>& getInstance(void);

    void hello (void) {
       std::cout << "Hello!\n" << std::endl;
    }

    Singleton(const Singleton&) = delete;
    Singleton(Singleton&&) = delete;
    Singleton& operator=(const Singleton&) = delete;
    Singleton& operator=(Singleton&&) = delete;

private:
    static std::unique_ptr<Singleton, decltype(&Singleton::deleter)> s_instance_;

    Singleton() { std::cout << "Constructed\n" << std::endl; }

    ~Singleton() { std::cout << "Destroyed\n" << std::endl; }

};

std::unique_ptr<Singleton, decltype(&Singleton::deleter)>&
Singleton::getInstance (void)
{
    if (s_instance_ == nullptr) {
        s_instance_ = std::unique_ptr<Singleton, decltype(&Singleton::deleter)>(new Singleton(), &Singleton::deleter);
    }

    return s_instance_;
}

std::unique_ptr<Singleton, decltype(&Singleton::deleter)> Singleton::s_instance_{nullptr};

int main ()
{
    bool some_condition = true;
    std::unique_ptr<Singleton, decltype(&Singleton::deleter)> &ins = Singleton::getInstance();

    ins->hello();

    if (some_condition) {
       ins.reset();
    }

    std::cout << "End of main\n" << std::endl;
    return 0;
}

这给 g++ (--version == g++ (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609) 带来以下错误

In file included from /usr/include/c++/5/memory:81:0,
                 from uptr.cpp:2:
/usr/include/c++/5/bits/unique_ptr.h: In instantiation of ‘constexpr std::unique_ptr<_Tp, _Dp>::unique_ptr() [with _Tp = Singleton; _Dp = void (*)(Singleton*)]’:
/usr/include/c++/5/bits/unique_ptr.h:200:61:   required from ‘constexpr std::unique_ptr<_Tp, _Dp>::unique_ptr(std::nullptr_t) [with _Tp = Singleton; _Dp = void (*)(Singleton*); std::nullptr_t = std::nullptr_t]’
uptr.cpp:44:89:   required from here
/usr/include/c++/5/bits/unique_ptr.h:159:9: error: static assertion failed: constructed with null function pointer deleter
       { static_assert(!is_pointer<deleter_type>::value,
         ^

另外,有没有办法可以缩短std::unique_ptr<Singleton, decltype(&Singleton::deleter)>我在类定义之前尝试使用以下方法,但编译器因类型不完整而出错:

using SingletonUPtr = std::unique_ptr<Singleton, decltype(&Singleton::deleter)>;
Yakk - Adam Nevraumont

不需要同时存储类型和值。类型可以做调度。

你可以只写这个玩具:

template<class F, F f>
struct call_t {
  constexpr operator F() const{ return f; }
};

这神奇的作品。(当您使用 调用它时(),C++ 会查找到函数指针的转换)。这是std::integral_constant缺少的部分功能的实现在这种情况下,我将它用作调用 type 的常量评估值的类型它还有其他(类似的)用途。fF

尝试这个:

void foo() { std::cout << "hello world\n"; }
int main() {
  using foo_t = call_t< void(*)(), foo >;
  foo_t foo_v = {};
  foo_v(); // hello world
  foo_t{}(); // hello world
  std::cout << sizeof(foo_t) << "\n"; // 1, object is stateless
  std::cout << sizeof(&foo) << "\n"; // 4 or 8, pointer has state
}

  

其余的看起来像:

class Singleton {

public:

    static void deleter(Singleton* p) {
        delete p;
        std::cout << "In deleter\n" << std::endl;
    }
    using upSingleton = std::unique_ptr<Singleton, call_t<decltype(&Singleton::deleter), &Singleton::deleter> >;

    static upSingleton& getInstance(void);

    void hello() {
       std::cout << "Hello!\n" << std::endl;
    }

    Singleton(const Singleton&) = delete;
    Singleton(Singleton&&) = delete;
    Singleton& operator=(const Singleton&) = delete;
    Singleton& operator=(Singleton&&) = delete;

private:
    static upSingleton s_instance_;

    Singleton() { std::cout << "Constructed\n" << std::endl; }

    ~Singleton() { std::cout << "Destroyed\n" << std::endl; }
};

Singleton::upSingleton&
Singleton::getInstance()
{
    if (s_instance_ == nullptr) {
        s_instance_ = upSingleton(new Singleton());
    }

    return s_instance_;
}

Singleton::upSingleton Singleton::s_instance_{nullptr};

int main()
{
    bool some_condition = true;
    Singleton::upSingleton &ins = Singleton::getInstance();

    ins->hello();

    if (some_condition) {
       ins.reset();
    }

    std::cout << "End of main\n" << std::endl;
    return 0;
}

活生生的例子

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章