如何将 class 的静态方法作为 std::unique_ptr 的删除器传递?
How to pass static method of the class as deleter for std::unique_ptr?
我一直在尝试将遵循 class 的静态方法传递为 unique_ptr
的 deleter
,但我无法找出正确的语法。
如果我刚开始使用 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)>
吗?我尝试在 class 定义之前使用以下方法,但编译器因类型不完整而出错:
using SingletonUPtr = std::unique_ptr<Singleton, decltype(&Singleton::deleter)>;
错误在第 44 行,这似乎是 Singleton::s_instance_
变量的定义。您不在那里提供删除功能。您应该将其包含在定义中,就像您之前在 getInstance
.
中所做的那样
std::unique_ptr<Singleton, decltype(&Singleton::deleter)> Singleton::s_instance_{nullptr, &Singleton::deleter};
不需要同时存储类型和值。该类型可以进行调度。
在c++11中你可以只写这个玩具:
template<class F, F f>
struct call_t {
constexpr operator F() const{ return f; }
};
神奇的效果。 (当您使用 ()
调用它时,C++ 会查找到函数指针的转换)。这是 std::integral_constant
的一部分的实现,但 c++11 中缺少一些功能。在这种情况下,我将其用作调用类型 F
的常量评估值 f
的类型。它还有其他(类似)用途。
试试这个:
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;
}
我一直在尝试将遵循 class 的静态方法传递为 unique_ptr
的 deleter
,但我无法找出正确的语法。
如果我刚开始使用 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)>
吗?我尝试在 class 定义之前使用以下方法,但编译器因类型不完整而出错:
using SingletonUPtr = std::unique_ptr<Singleton, decltype(&Singleton::deleter)>;
错误在第 44 行,这似乎是 Singleton::s_instance_
变量的定义。您不在那里提供删除功能。您应该将其包含在定义中,就像您之前在 getInstance
.
std::unique_ptr<Singleton, decltype(&Singleton::deleter)> Singleton::s_instance_{nullptr, &Singleton::deleter};
不需要同时存储类型和值。该类型可以进行调度。
在c++11中你可以只写这个玩具:
template<class F, F f>
struct call_t {
constexpr operator F() const{ return f; }
};
神奇的效果。 (当您使用 ()
调用它时,C++ 会查找到函数指针的转换)。这是 std::integral_constant
的一部分的实现,但 c++11 中缺少一些功能。在这种情况下,我将其用作调用类型 F
的常量评估值 f
的类型。它还有其他(类似)用途。
试试这个:
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;
}