C++ 什么';make_pair和pair有什么不同?

C++ 什么';make_pair和pair有什么不同?,c++,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 call

如果您运行下面的代码,您将打印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(); 
                });
}
使用Callback=std::函数;
结构测试
{
void运算符()()
{
std::cout如此类推,
std::ref
不能与
测试或
一起工作,如下所示:

std::vector<std::pair<Callback, int>> test_vtor; 
无法避免您的
回调被复制。
这与不允许声明
std::pair
的原因相同

即使对
std::reference\u wrapper
有以下例外规则:

std::vector<std::pair<Callback, int>> test_vtor; 
…除非应用std::Decage会导致某些类型的
X
出现
std::reference\u包装器
,在这种情况下,推断的类型是
X&


test\u vtor
中总会有一个新的
回调副本(无论是移动的还是复制的),这将在构造过程中超过其引用性。

是的,应该打开引用包装。嗯,不完全是这样。
std::reference\u包装
被转换为
T&
,它确实保持了引用性。它实际上与
test\u vtor相同。推回(std::pair(test\u map[1])
,这也不起作用。引用性稍后会丢失。@hvd,你是对的。
std::ref
确实保留了引用性。我的意思是,引用性稍后会因为
std::make\u pair
而丢失。IMO引用性会在
std::decay
中丢失,这被推断为
std::remove\u cv::type
Bu这就是我的观点:它不是。引用性不会因为
std::make_-pair
而丢失。生成的
std::pair
test_-map[1]
作为引用。它是
回调的构造(也称
std::function
)引用丢失的地方。@DeanSeo
std::decable::type
只是
std::reference\u wrapper
std::make\u pair
然后有一个特殊的异常,将其转换为
T&
Callback
然后按值获取(不涉及
std::decable
)。