Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/157.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 对从引用到std::reference\u包装或编译器错误的隐式转换理解不正确?_C++_Reference_Implicit Conversion_Reference Wrapper - Fatal编程技术网

C++ 对从引用到std::reference\u包装或编译器错误的隐式转换理解不正确?

C++ 对从引用到std::reference\u包装或编译器错误的隐式转换理解不正确?,c++,reference,implicit-conversion,reference-wrapper,C++,Reference,Implicit Conversion,Reference Wrapper,我对一些涉及引用和std::reference_包装的代码感到困惑,我根本不清楚这是否是我的错,因为我误解了引用包装的工作原理,或者我遇到了编译器错误 我有一个简单的映射,将对复杂类中对象的引用与值配对: std::unordered_map<Object const &obj, int32_t value> myMap; 但这段代码虽然可以编译,但不起作用。但是,这一点与预期一样有效: void myFunction(Object const &obj, int3

我对一些涉及引用和std::reference_包装的代码感到困惑,我根本不清楚这是否是我的错,因为我误解了引用包装的工作原理,或者我遇到了编译器错误

我有一个简单的映射,将对复杂类中对象的引用与值配对:

std::unordered_map<Object const &obj, int32_t value> myMap;
但这段代码虽然可以编译,但不起作用。但是,这一点与预期一样有效:

void myFunction(Object const &obj, int32_t value)
{
    ...
    myMap.emplace(std::pair<std::reference_wrapper<const Object>, int32_t>(obj, value));
}
void myFunction(对象常量和对象,int32_t值)
{
...
放置(std::pair(obj,value));
}
(注意,在第二个版本中,我仍然没有显式地构建obj的引用包装器)

因此,我的疑问是:

我是否误解了引用包装器的用法?没有从引用到引用的隐式转换?如果不是,为什么代码首先要编译


或者这是std::make_pair中的已知问题/缺陷,无法正确扣除传递给它的类型?

std::make_pair
从不(1)将引用类型推断为该对中的一种类型,它总是生成值类型。因此对
emplace
的调用接收一个临时
std::pair
作为参数。然后,引用包装器将从此临时对初始化,这意味着它将绑定到此临时对的
第一个
成员

在第二种情况下,临时的类型是
std::pair
(因为您已经明确请求了它),这意味着临时对中有一个引用包装器,直接绑定到
obj
。然后,映射内的引用包装将从此临时引用包装中复制,从而直接引用
obj

(1) “从不”在这里不是真的。有一个例外:当
std::make_pair
的一个参数的类型为
std::reference_wrapper
时,该对中的类型将被减少到
T&
。这实际上为您提供了正确的解决方案:将
obj
包装在
std::cref
内的
make\u pair
调用:

myMap.emplace(std::make_pair(std::cref(obj), value));
这将导致临时对包含一个引用,并且映射中的
reference\u包装将绑定到其引用的对象(
obj
),这正是您想要的

void myFunction(Object const &obj, int32_t value)
{
    ...
    myMap.emplace(std::pair<std::reference_wrapper<const Object>, int32_t>(obj, value));
}
myMap.emplace(std::make_pair(std::cref(obj), value));