C++ 在可变模板中复制的参考参数

C++ 在可变模板中复制的参考参数,c++,pass-by-reference,variadic-templates,C++,Pass By Reference,Variadic Templates,我有一个事件类,它将一组弱ptr(观察者)元组存储到一个函数中,该函数在事件“触发”时执行 示例中的函数类型为:void(int&)。也就是说,我想触发传递对值的引用的事件,让观察者更改该值,并验证该值是否已在观察对象中更改回。顺便说一句,事件实现是可变的,这可能会使问题复杂化(至少是代码) 目前这是失败的。沿着这条线的某个地方,引用正在被转换为非引用或复制,但我看不到在哪里 完整回购协议如下。注意:assert(value!=10)失败,即使我在事件处理程序中将该值设置为1 #include

我有一个事件类,它将一组弱ptr(观察者)元组存储到一个函数中,该函数在事件“触发”时执行

示例中的函数类型为: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;
}
#包括
#包括
#包括
#包括
#包括
模板
班级活动
{
公众:
模板
void运算符()(Args…Args)
{
for(自动常量和侦听器:侦听器)
{
if(auto-locked=std::get(listener).lock())
std::get(侦听器)(args…);
}       
}
模板
无效附加(P(Q::*f)(参数…,标准::共享\u ptr const&P)
{
自动w=标准::弱ptr(p);
自动l=[w,f](参数…参数){
如果(自动锁定=w.lock())
return(*locked.get()*f)(args;
其他的
返回P();
};
push_back(std::make_tuple(std::weak_ptr(w,l));
}
typedef std::元组事件\元组;
向量侦听器;
};
观察到的类:public std::从\u this
{
公众:
int值;
虚火
{
数值=10;
事件(值);
断言(值!=10);
}
事件事件;
};
类观察者:public std::从\u中启用\u共享\u
{
公众:
无效附加(标准::共享\u ptr const&observed)
{
observed->TheEvent.Attach(&Observer::OneEvent,从_this()共享的_);
}
void OnEvent(int和value)
{
断言(值==10);
数值=1;
}
};
内部主(空)
{
自动观察=标准::使_共享();
auto observer1=std::make_shared();
观察者1->附加(已观察);
观察->火灾();
返回0;
}
事件::运算符()按值获取参数。改写如下:

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)...);
    }       
}
模板
void运算符()(Args&&…Args)
{
for(自动常量和侦听器:侦听器)
{
if(auto-locked=std::get(listener).lock())
std::get(侦听器)(std::forward(args)…);
}       
}

Event::operator()
按值获取
args
。好的,但在可变参数包中,我可能希望,例如,一些按值获取,一些按引用获取。如果我通过了&,那还会发生吗?啊,我得到了相反的问题。因此,似乎我必须在通过引用传递还是通过值传递之间进行选择。我不能把它们混在一起,也就是说,我的函数不能是void(int,int&)。那应该可以
OnEvent
可以随心所欲地接受其参数。
Event::operator()
通过引用获取的事实并没有改变这一点。是的,我只是用int,int&做了一个测试,第一个参数没有改变,第二个是。所以它起作用了!谢谢你,罗宾逊
Event::operator()
通过引用获取所有参数(适合每个参数的任何参数),并将它们传递给处理程序函数,处理程序函数通过引用或值获取它们,这无关紧要。