gpt4 book ai didi

c++ - 安全回调提供程序(SFINAE、std::forward 和重载解析)

转载 作者:行者123 更新时间:2023-11-27 23:44:33 27 4
gpt4 key购买 nike

我正在研究一种创建“安全”回调的机制,该机制在其父对象被销毁后调用时不会导致未定义的行为。该类应该足够通用以能够包装任何回调,void(...) 回调只是被执行或不被执行,具体取决于它们绑定(bind)到的对象的状态,以及返回值返回提升的回调::optional with the returned value, if executed, or boost::none if not executed.The implementation is lost complete, 但是有两件事让我担心我不完全理解我的代码...

如果第 19 行被取消注释,第 18 行被注释掉,模板将无法编译——这仅仅是一个可以解决的语法问题,还是我试图错误地使用 result_of 机制(那里的 std::forward 是否改变了语义还是多余的?)

如果第 88 行未注释掉而第 89 行被注释掉,则由于函数调用 fun 的歧义导致编译失败,我不太明白 - 在我看来 fun(int&&) 是完全匹配的,那么为什么编译器会提示 fun(int) 版本不明确?

如果还有其他细微(或严重)错误,请一并评论。

谢谢。

#include <iostream>
#include <string>
#include <type_traits>
#include <utility>
#include <memory>
#include <boost/optional.hpp>

template<class Func>
class SafeCallback
{
public:
SafeCallback(std::shared_ptr<bool> guard, const Func& callback)
: guard_(guard)
, callback_(callback)
{}

template<class... Args>
// auto operator()(Args&&... args) -> typename std::enable_if<std::is_void<typename std::result_of<Func(std::forward<Args>(args)...)>::type>::value, // won't compile with: 19:91: error: invalid use of template-name 'std::result_of' without an argument list
auto operator()(Args&&... args) -> typename std::enable_if<std::is_void<typename std::result_of<Func(Args...)>::type>::value,
void>::type
{
std::cout << "trying void callback" << std::endl;
if(guard_.lock())
{
std::cout << "callback is still alive :)" << std::endl;
callback_(std::forward<Args>(args)...);
return;
}
std::cout << "uh-oh, callback is dead!" << std::endl;
}

template<class... Args>
auto operator()(Args&&... args) -> typename std::enable_if<!std::is_void<typename std::result_of<Func(Args...)>::type>::value,
boost::optional<typename std::result_of<Func(Args...)>::type>>::type
{
std::cout << "trying non-void callback" << std::endl;
if(guard_.lock())
{
std::cout << "callback is still alive :)" << std::endl;
return callback_(std::forward<Args>(args)...);
}
std::cout << "uh-oh, callback is dead!" << std::endl;
return boost::none;
}

bool isAlive()
{
return guard_.lock();
}

private:
std::weak_ptr<bool> guard_;
Func callback_;
};

class SafeCallbackProvider
{
public:
SafeCallbackProvider()
: guard_(new bool(true))
{}

virtual ~SafeCallbackProvider() = default;

template<class Func>
SafeCallback<Func> makeSafeCallback(const Func& callback)
{
return SafeCallback<Func>(guard_, callback);
}

private:
std::shared_ptr<bool> guard_;
};

struct A : SafeCallbackProvider
{
void fun()
{
std::cout << "---this is fun---" << std::endl;
}

int fun(int&& i)
{
std::cout << "&& this is && " << i << " && fun &&" << std::endl;
return i;
}

// int fun(int i) // fails to compile with: 123:48: error: call of overloaded 'fun(int)' is ambiguous
int fun(int& i)
{
std::cout << "---this is ---" << i << "--- fun---" << std::endl;
return i;
}
};

int main()
{
A* a= new A;
auto cb = a->makeSafeCallback(
[&]()
{
a->fun();
});
cb();
delete a;
cb();

std::cout << "\n----------\n\n";

A* a2= new A;
auto cb2 = a2->makeSafeCallback(
[&](int i)
{
return a2->fun(i);
});
cb2(5);
delete a2;
cb2(5);

std::cout << "\n----------\n\n";

A* a3= new A;
auto cb3 = a3->makeSafeCallback(
[&](int&& i)
{
return a3->fun(std::forward<int>(i));
});
cb3(5);
delete a3;
cb3(5);
return 0;

}

最佳答案

注意:这只回答了第一个问题,因为我显然有一只苍蝇的注意力。更多即将推出。


std::result_of 本质上是根据看起来像函数 call 的函数 type 执行一些魔法。在有效的行中:

typename std::result_of<Func(Args...)>::type

这是预期用途,模拟调用 Func 的实例,其值类型为 Args...。另一方面:

typename std::result_of<Func(std::forward<Args>(args)...)>::type

这会将 Argsargs 扩展为一组 values,然后形成 链,- functoin 样式中的运算符强制转换为 Func。整个事情是一个表达式,而不是 std::result_of 期望的类型。

看起来您已经使用 decltype 进行了一半,它看起来像:

decltype(std::declval<Func&>()(std::forward<Args>(args)...))

... 或者,如果您不厌其烦地将它移到 callback_ 的声明下方:

decltype(callback_(std::forward<Args>(args)...))

关于c++ - 安全回调提供程序(SFINAE、std::forward 和重载解析),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51706772/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com