在可变参数模板中复制的参考参数
Reference parameter being copied in variadic template
我有一个事件 class,它将一组 weak_ptr(观察者)的元组存储到一个函数中,该函数在事件为 "fired" 时执行。
示例中函数类型为:void(int &)。也就是说,我想触发传递对值的引用的事件,让观察者更改该值并验证该值是否已在被观察对象中改回。顺便说一句,事件实现是可变的,这可能会使问题复杂化(至少代码)。
目前这是失败的。沿线的某处,参考被转换为非参考或被复制,但我看不到在哪里。
完整的回购协议如下。注意 assert (value != 10) 失败,即使我在事件处理程序中将值设置为 1。
#include <memory>
#include <tuple>
#include <vector>
#include <cassert>
#include <functional>
template<class FunctionPrototype>
class Event
{
public:
template<typename... Args>
void operator()(Args... args)
{
for (auto const & listener : Listeners)
{
if (auto locked = std::get<0>(listener).lock())
std::get<1>(listener)(args...);
}
}
template<typename P, typename Q, typename R, typename... Args>
void Attach(P(Q::*f)(Args...), std::shared_ptr<R> const & p)
{
auto w = std::weak_ptr<R>(p);
auto l = [w, f](Args... args) {
if (auto locked = w.lock())
return (*locked.get().*f)(args...);
else
return P();
};
Listeners.push_back(std::make_tuple(std::weak_ptr<void>(w), l));
}
typedef std::tuple<std::weak_ptr<void>, std::function<FunctionPrototype>> event_tuple;
std::vector<event_tuple> Listeners;
};
class Observed : public std::enable_shared_from_this < Observed >
{
public:
int value;
void Fire()
{
value = 10;
TheEvent(value);
assert(value != 10);
}
Event<void(int &)> TheEvent;
};
class Observer : public std::enable_shared_from_this<Observer>
{
public:
void Attach(std::shared_ptr<Observed> const & observed)
{
observed->TheEvent.Attach(&Observer::OnEvent, shared_from_this());
}
void OnEvent(int & value)
{
assert(value == 10);
value = 1;
}
};
int main(void)
{
auto observed = std::make_shared<Observed>();
auto observer1 = std::make_shared<Observer>();
observer1->Attach(observed);
observed->Fire();
return 0;
}
Event::operator()
按值获取参数。改写如下:
template<typename... Args>
void operator()(Args&&... args)
{
for (auto const & listener : Listeners)
{
if (auto locked = std::get<0>(listener).lock())
std::get<1>(listener)(std::forward<Args>(args)...);
}
}
我有一个事件 class,它将一组 weak_ptr(观察者)的元组存储到一个函数中,该函数在事件为 "fired" 时执行。
示例中函数类型为:void(int &)。也就是说,我想触发传递对值的引用的事件,让观察者更改该值并验证该值是否已在被观察对象中改回。顺便说一句,事件实现是可变的,这可能会使问题复杂化(至少代码)。
目前这是失败的。沿线的某处,参考被转换为非参考或被复制,但我看不到在哪里。
完整的回购协议如下。注意 assert (value != 10) 失败,即使我在事件处理程序中将值设置为 1。
#include <memory>
#include <tuple>
#include <vector>
#include <cassert>
#include <functional>
template<class FunctionPrototype>
class Event
{
public:
template<typename... Args>
void operator()(Args... args)
{
for (auto const & listener : Listeners)
{
if (auto locked = std::get<0>(listener).lock())
std::get<1>(listener)(args...);
}
}
template<typename P, typename Q, typename R, typename... Args>
void Attach(P(Q::*f)(Args...), std::shared_ptr<R> const & p)
{
auto w = std::weak_ptr<R>(p);
auto l = [w, f](Args... args) {
if (auto locked = w.lock())
return (*locked.get().*f)(args...);
else
return P();
};
Listeners.push_back(std::make_tuple(std::weak_ptr<void>(w), l));
}
typedef std::tuple<std::weak_ptr<void>, std::function<FunctionPrototype>> event_tuple;
std::vector<event_tuple> Listeners;
};
class Observed : public std::enable_shared_from_this < Observed >
{
public:
int value;
void Fire()
{
value = 10;
TheEvent(value);
assert(value != 10);
}
Event<void(int &)> TheEvent;
};
class Observer : public std::enable_shared_from_this<Observer>
{
public:
void Attach(std::shared_ptr<Observed> const & observed)
{
observed->TheEvent.Attach(&Observer::OnEvent, shared_from_this());
}
void OnEvent(int & value)
{
assert(value == 10);
value = 1;
}
};
int main(void)
{
auto observed = std::make_shared<Observed>();
auto observer1 = std::make_shared<Observer>();
observer1->Attach(observed);
observed->Fire();
return 0;
}
Event::operator()
按值获取参数。改写如下:
template<typename... Args>
void operator()(Args&&... args)
{
for (auto const & listener : Listeners)
{
if (auto locked = std::get<0>(listener).lock())
std::get<1>(listener)(std::forward<Args>(args)...);
}
}