1
我有這樣的代碼,嘗試的模板參數完美轉發通過中間類裝入std::function
:Rvalue引用參數在通過std :: forward傳遞時到期?
#include <functional>
#include <vector>
#include <algorithm>
#include <iterator>
#include <memory>
#include <iostream>
template <typename ...Arguments>
class CSignal
{
public:
typedef std::function<void (Arguments...)> SignalFunction;
public:
void connect(const SignalFunction& target)
{
m_connections.emplace_back(std::make_shared<SignalFunction>(target));
}
template <typename ...ActualArguments>
void invoke(ActualArguments&&... args) const
{
for (auto& connection: m_connections)
if (connection)
(*connection)(std::forward<ActualArguments>(args)...);
}
private:
std::vector<std::shared_ptr<SignalFunction>> m_connections;
};
struct A
{
void f() {std::cout << __FUNCTION__ << "\n";}
};
void test(std::shared_ptr<A> ptr)
{
if (ptr)
ptr->f();
}
int main()
{
CSignal<std::shared_ptr<A>> signal;
signal.connect(test);
signal.connect(test);
signal.invoke(std::make_shared<A>());
return 0;
}
問題:test
叫了兩次,它就是所謂它的參數,第二次是empty
指針。爲什麼?
如果我刪除std::forward
問題消失,但那不是我想要的。
對不起,我不明白,你能擴大答案嗎?我的理解是,所有'std :: move'都會返回它的參數作爲右值引用,從而失去參數的名稱以使其成爲右值。但是原始的'args'參數在外部範圍中繼續存在(並且它是一個左值,即使它是rvalue,其中'invoke'被調用),它爲什麼會被破壞?這裏本身沒有任何動作,只是參數傳遞! –
@VioletGiraffe'std :: move'(有時候是'std :: forward')導致它的參數被解釋爲一個右值,這可能導致過期發生在一個函數中,該函數明確將其作爲右值接收。前進/移動助手功能產生一個特權,可以通過例如'test'。在這種情況下,'test'總是使右值變元無效。 – Potatoswatter
好吧,讓我們說我只是想讓它工作,所以我刪除了'std :: forward'。是否有另外一個包裝,我應該使用呢? –