make_pair和pair之间有什么不同?

时间:2018-05-07 10:11:27

标签: c++

如果您运行以下代码,则会打印3412,这意味着std::make_pair忽略了std::ref。我想了解这里发生了什么?

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(); 
                });
}

1 个答案:

答案 0 :(得分:2)

因此在from this answer上,std::ref不能与test_vtor一起使用,如下所示:

std::vector<std::pair<Callback, int>> test_vtor; 

即使您传递参考:

test_vtor.push_back(std::make_pair(std::ref(test_map[1]), 1));

无法避免被Callback复制。 这与宣布std::pair<Callback&, int>不被允许的原因相同。

即使std::make_pair具有std::reference_wrapper的例外规则,如下所示:

  

...除非对某些类型std::reference_wrapper<X>应用std :: decay导致 X,在这种情况下推导出的类型为X& 。< / p>

Callback中总会有test_vtor的新副本(无论是移动还是复制),在构建过程中都会超过其参考值。