Reputation: 3487
If you run the below code, you will print 3412, which mean std::make_pair
ignored the std::ref
here. I want to do understand what is happening here?
using Callback = std::function<void ()>;
struct Test
{
void operator()()
{
std::cout << a ;
};
int a;
};
struct Sub
{
void Subscribe(Callback callback)
{
callback_ = callback;
}
void trigger()
{
callback_();
}
Callback callback_;
};
int main() {
std::vector<std::pair<Callback, int>> test_vtor;
std::unordered_map<int, Test > test_map;
test_map[1].a = 1;
test_map[2].a = 2;
test_vtor.push_back(std::pair<Callback, int>(std::ref(test_map[1]), 1));
test_vtor.push_back(std::pair<Callback, int>(std::ref(test_map[2]), 2));
test_vtor.push_back(std::make_pair(std::ref(test_map[1]), 1));
test_vtor.push_back(std::make_pair(std::ref(test_map[2]), 2));
test_map[1].a = 3;
test_map[2].a = 4;
std::for_each(test_vtor.begin(),
test_vtor.end(),
[&](auto& pair){
pair.first();
});
}
Upvotes: 1
Views: 736
Reputation: 5683
So on from this answer, std::ref
does not work with test_vtor
as follows:
std::vector<std::pair<Callback, int>> test_vtor;
Even if you pass a reference:
test_vtor.push_back(std::make_pair(std::ref(test_map[1]), 1));
you cannot avoid your Callback
being copied.
That's the same reason that declaring std::pair<Callback&, int>
is not allowed.
Even if std::make_pair
has this exceptional rule for std::reference_wrapper
as follows:
... unless application of std::decay results in
std::reference_wrapper<X>
for some typeX
, in which case the deduced type isX&
.
There will be always a new copy of Callback
in test_vtor
(whether it's moved or copied), which will surpass its reference-ness during the construction.
Upvotes: 2