打破C+的变化+;11带make_对(_Ty1&;u Val1,const_Ty2&;u Val2) 考虑以下C++程序 #include<map> #include<iostream> int main() { int a = 5, b = 7; auto pair = std::make_pair<int, int>(a,b); return 0; }
我从这次失败中了解到的是打破C+的变化+;11带make_对(_Ty1&;u Val1,const_Ty2&;u Val2) 考虑以下C++程序 #include<map> #include<iostream> int main() { int a = 5, b = 7; auto pair = std::make_pair<int, int>(a,b); return 0; },c++,visual-c++,stl,c++11,g++,C++,Visual C++,Stl,C++11,G++,我从这次失败中了解到的是 VC11和我假设gcc-4.7.2只有一个std::make_pairmake_pair(_Ty1&&u Val1,const_Ty2&&u Val2)的实现,它只能接受右值引用。以前的VC++版本示例VC10有两个版本,一个接受左值,另一个接受右值引用 右值引用不能用于初始化非常量引用,即int&a=b*5无效 我可以使用std::move将lvalue转换为rvalue引用,调用就会成功 由于std::make_pair为每个参数接受两种不同的类型,因此在所有可能的
make_pair(_Ty1&&u Val1,const_Ty2&&u Val2)的实现,它只能接受右值引用。以前的VC++版本示例VC10有两个版本,一个接受左值,另一个接受右值引用
int&a=b*5
无效std::move
将lvalue
转换为rvalue
引用,调用就会成功std::make_pair
为每个参数接受两种不同的类型,因此在所有可能的情况下,模板参数解析都可以解析参数的类型,并且不需要显式指定类型auto pair = std::make_pair(a,b);
- 现在,我的问题是,从库中删除左值实现的驱动因素是什么李>
- 是否有可能知道以类似方式更改的任何其他库函数
- 当我需要针对G+、CC、ACC、XL C++等多个编译器时,如何处理这些情况,编译器要么没有升级,要么编译器不支持rValor引用或移动语义。
std::make_pair
存在的唯一目的是利用类型推断来避免键入类型名称。这就是为什么只有一个重载(它应该有两个重载,而不是VC认为的一个通用引用和一个对const的左值引用)
模板
constexpr对构成双(T1和x,T2和y);
如果要显式地键入类型,只需使用pair构造函数即可。它甚至更短
auto pair = std::pair<int, int>(a,b);
auto-pair=std::pair(a,b);
当您执行std::make_pair
时,您将强制将模板参数T1
和T2
都推断为int
。这将为您提供函数作为std::pair make_pair(int&&,int&&)
。现在这些参数只能接受右值,因为它们是右值引用
然而,当通过模板类型推断来推断T1
和T2
的类型时,它们充当“通用参考”。也就是说,如果它们收到左值参数,它们将是左值引用,如果它们收到右值参数,它们将是右值引用。这使make_pair
能够实现完美的转发
关键是,不要显式地给出模板类型参数。
make_pair
的全部意义在于它可以推断类型本身。如果你命名了类型,它就不能再做完美的转发,并且会因为左值参数而失败。好吧,这不是一个突破性的改变,因为到底是谁使用带有显式模板实例化的std::make\u pair
?它的明确设计是为了从自动类型推断中获益。因此,由于很少有人会编写std::make_-pair
来支持std::make_-pair
,因此没有多少代码需要破解。不过,这是一个不错的发现。不幸的是,我遇到了指定显式类型的代码。我相信这与感谢您的回答中讨论的问题是一样的。尽管经过艰苦的努力,我还是明白了上述事实。顺便说一句,你能解释一下什么是universalreference
吗?这个术语对我来说是新的。你还知道其他库函数是否也有类似的变化吗?@Abhijit我添加了一个链接到Scott Meyer的解释(他提出了这个术语)。如果不使用类型推断,任何其他用于相同目的(利用类型推断)的库函数都可能不起作用。它们的形式通常是make\u something
,比如make\u tuple
。关键是它们不能与显式类型一起工作,因为它们对显式类型没有用处。@Abhijit很清楚,“通用引用”只是一个口语术语。它们实际上只是右值引用,但由于模板类型推断和引用折叠规则,它们有一个有趣的特性——它们有时表现为左值引用,有时表现为右值引用。仔细想想,我们应该称之为左值-右值二元性。谢谢你们和@sftrabbit花时间回答我的疑问。
template <class T1, class T2>
constexpr pair<V1, V2> make_pair(T1&& x, T2&& y);
auto pair = std::pair<int, int>(a,b);