gpt4 book ai didi

c++ - 如何像类一样为 std::function 实现类型橡皮擦?

转载 作者:太空狗 更新时间:2023-10-29 23:15:12 26 4
gpt4 key购买 nike

我想把几个方法指针放在一个容器中,所以我实现了一个简单的std::function——就像模板类:

template<typename ...Args>
class MethodHolder : MethodHolderBase
{
public:
typedef void(*MethodType)(Args...);
MethodHolder(MethodType method) : method(method) {}
virtual ~MethodHolder() {}

void Invoke(Args... args)
{ method(args...); }

private:
MethodType method;
};

它有一个基类,所以我可以这样写代码:

void func(int);
...
std::vector<MethodHolderBase*> funcs;
funcs.push_back(new MethodHolder<int>(&func));
...

然后我添加一个包装器以从 MethodHolderBase 调用 Invoke():

class Method
{
public:
...//constructors, assignment operator, destructor
template<typename ...Args>
void Invoke(Args&&... args)
{
auto pHolder = dynamic_cast<MethodHolder<Args...>*>(pBase);
if (pHolder)
pHolder->Invoke(args...);
}
private:
MethodHolderBase* pBase;
}

现在,我可以将 Method 的一些实例放入容器中,并调用 Invoke() 来调用函数。有效。但是一旦我将 func 的声明更改为:

void func(int&&);

似乎无论我将哪种类型传递给Method::Invoke(),都不会推导出int&&,所以dynamic_cast 失败。

我应该对 Method::Invoke 做一些修改吗?如果是这样,如何?或者有不同的解决方案?

最佳答案

您应该通过 std::forward 使用完美转发 ,否则您的右值/左值引用将不会被保留(更多信息 see this beautiful answer ):

void Invoke(Args&&... args)
// ^^
{ method(std::forward<Args>(args)...); }
// ^^^^^^^^^^^^^^^^^^^ ^

然后:

template<typename ...Args>
void Invoke(Args&&... args)
{
auto pHolder = dynamic_cast<MethodHolder<Args&&...>*>(pBase);
// ^^
if (pHolder)
pHolder->Invoke(std::forward<Args>(args)...);
// ^^^^^^^^^^^^^^^^^^^ ^
}

关于c++ - 如何像类一样为 std::function 实现类型橡皮擦?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30272694/

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