Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.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+的变化+;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++ - Fatal编程技术网

打破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为每个参数接受两种不同的类型,因此在所有可能的

我从这次失败中了解到的是

  • VC11和我假设gcc-4.7.2只有一个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);