lundi 29 décembre 2014

Rvalue reference parameter expires when passed via std::forward?

I have this code that attempts perfect forwarding of template parameters pack into std::function via intermediate class:



#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;
}


Problem: test is called twice, and the second time it's called its parameter is empty pointer. Why?


If I remove std::forward the issue disappears, but that's not what I want.


Aucun commentaire:

Enregistrer un commentaire