gpt4 book ai didi

C++11 std::forward 一个指针

转载 作者:可可西里 更新时间:2023-11-01 17:36:46 26 4
gpt4 key购买 nike

我有一个 Signal我的应用程序中的类为类提供了公开事件的选项(与 .NET 中相同)。

类(class)正常,一切顺利。

昨天我看到this SO question (and its answer)并熟悉std::forward .

我决定尝试在我的代码中使用它,所以我更改了每个 std::function<void(Args...)>std::function<void(Args&&...)>在 raise 函数(operator())中,我使用了我在上面链接中看到的相同逻辑,所以现在该函数采用 Args&&...args并且回调使用 std::forward<Args>(args)...

这是我的 Signal 类的简化版本(为了使其成为一个很好的示例而进行了一些更改):

template<typename... Args> class Signal
{
public:
int operator+=(const std::function<void(Args&&...)>& func) {
int token = getNewToken();
m_subscribers.emplace(token, func);
return token;
}

void operator()(Args&&... args) {
for (auto it : m_subscribers) {
it.second(std::forward<Args>(args)...);
}
}

private:
std::map<int, std::function<void(Args&&...)>> m_subscribers;
};

int main() {
int* six = new int(6);
int seven = 7;

Signal<int*> e1;
e1 += [](int* x) { std::cout << *x; };

Signal<int> e2;
e2 += [](int x) { std::cout << x; };

e1(&seven);
e2(6);

e1(six); //Error C2664 'void Signal<int *>::operator ()(int *&&)':
// cannot convert argument 1 from 'int *' to 'int *&&'
e1(std::move(six)); //This is a workaround
return 0;
}

我看到的问题是类(或本例中的 main)试图用指针引发事件,我不确定如何解决这个问题。

我的主要目标是让 Signal 类成为通用 API,如果开发人员选择使用 Signal<int*>我不想让他/她用 std::move 加注.

我在这里做错了什么?

最佳答案

T&&如果 T 只是一个通用引用是非 cv 限定的函数模板参数。在您的电话接线员中:

void operator()(Args&&... args) {

Args不是函数的模板参数,它是类的模板参数。所以对于 Signal<int*> , 这个operator()int* 取一个右值引用.自 six是左值,失败。

您想要的是为 Signal 提供正确的引用资格.像这样:

template<typename... Args>
class Signal
{
using F = std::function<void(Args...)>; // NB: Just Args...
public:
int operator+=(F func) {
int token = getNewToken();
m_subscribers.emplace(token, std::move(func));
return token;
}

void operator()(Args... args) { // NB: just Args...
for (auto& it : m_subscribers) { // NB: auto&
it.second(args...);
}
}

private:
std::map<int, F> m_subscribers;
};

注意转发Args...无论如何是值得怀疑的。如果您有两个订阅者怎么办?一旦你转发了 args 一次,你就不能真正第二次使用它们。

以上将生成Signal<int*>做你期望的事。 operator()只需要 int* ,您可以将左值或右值传递给它。

关于C++11 std::forward 一个指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38723515/

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