我在我的应用程序中有一个Signal
类,它为类提供了一个公开事件(与.NET相同)的选项。C++ 11 std ::转发指针
班级运作良好。
昨天我看到this SO question (and its answer)并且熟悉了std::forward
。
我决定尝试在我的代码中使用它,所以我改为每std::function<void(Args...)>
到std::function<void(Args&&...)>
,并在提高功能(operator()
)我使用了我在上面的链接看到了同样的逻辑,所以现在该功能将Args&&...args
和回调使用std::forward<Args>(args)...
这里是我的信号类的简化版本(含部分变更,使之成为很好的例子):
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
在此示例中)尝试用普安特来举办活动rs和我不知道如何解决这个问题。
我的主要目标是让Signal类成为一个通用API,如果开发人员选择使用Signal<int*>
我不希望他用std::move
加注。
我在做什么错在这里?
@WernerErasmus是的。如果您有多个订户,则无法多次转发相同的参数。 – Barry
感谢Barry,除了'使用F'部分,这是我已经使用的代码。所以基本上你的答案是“你不能也不应该在这种情况下使用std :: forward”? – ZivS
我更关心如何以及如果我可以使用所有类型的std :: forward。我觉得我应该多读一些,因为你的答案的第一段对我来说有点核心...... – ZivS