在C ++ 11上有一个守护类,它负责在作用域退出时调用某个成员函数:
template <class T, void (T::*op)()>
struct Guard
{
Guard(T*g):
_g(g){}
~Guard()
{
(_g->*op)();
}
T*_g;
};
用法非常简单:
typedef Guard<Foo, &Foo::bar> FooGuard;
...
FooGuard g(&foo);
我的问题来自现有的shared_ptr<Foo>
。如何创建保留shared_ptr<T>
而不是T*
我已经尝试过:
template <class T, void (T::*op)()>
struct Guard<std::shared_ptr<T>, op>
{
Guard(std::shared_ptr<T>& g):
_g(g){}
~Guard()
{
((*_g).*op)();
}
std::shared_ptr<T> _g;
};
但是在编译G<std::shared_ptr<Foo>, &Foo::bar> g2(foo);
期间可以预见得到:
错误C2440:'specialization':无法从'overloaded-function'转换为'void(__thiscall std :: shared_ptr :: *)(void)'
答案 0 :(得分:1)
我建议改用lambda函数并按值捕获:
#include <functional>
#include <memory>
struct Guard
{
typedef std::function<void()> func_type;
Guard( const func_type& f ): func(f) {}
~Guard() { if (func) func(); }
func_type func;
};
struct Foo
{
void bar() {}
};
int main()
{
auto foo_ptr = std::make_shared<Foo>();
Guard g([foo_ptr](){ foo_ptr->bar(); }); // note the capture by value
}
请注意,如果您想保护在堆栈上分配的实例,也可以通过引用自由捕获。
答案 1 :(得分:1)
正如@PiotrSkotnicki已经指出的那样,你的专业化无效。 您可以使用类似下面的内容,但界面看起来不太好:
template <class T, class U, void (U::*op)()>
struct Guard
{
Guard(T*g):
_g(g){}
~Guard()
{
std::cout << "normal guard" << std::endl;
(_g->*op)();
}
T*_g;
};
template <class T, class U, void (U::*op)()>
struct Guard<std::shared_ptr<T>, U, op>
{
Guard(std::shared_ptr<T>& g):
_g(g){}
~Guard()
{
std::cout << "shared_ptr guard" << std::endl;
((*_g).*op)();
}
std::shared_ptr<T> _g;
};
<强>演示:强>
struct Foo
{
void bar()
{
std::cout << "Foo::bar()" << std::endl;
}
};
int main()
{
Foo foo;
{
typedef Guard<Foo, Foo, &Foo::bar> FooGuard;
FooGuard g(&foo);
}
std::shared_ptr<Foo> foo_ptr = std::make_shared<Foo>();
{
typedef Guard<std::shared_ptr<Foo>, Foo, &Foo::bar> FooGuard;
FooGuard g(foo_ptr);
}
return 0;
}
<强>输出:强>
normal guard
Foo::bar()
shared_ptr guard
Foo::bar()
答案 2 :(得分:1)
如果你真的想坚持丑陋的方式,我会建议使用删除器:
var date_res = $(this).find("td:nth-child(2)").find(".PL30").find("span").text();