C++11 make_pair with specified template parameters doesn't compile
我只是玩G+ + 4.7(稍后的快照之一),启用了STD=C++ 11。我试图编译一些现有的代码库,有一个失败的案例让我有些困惑。
如果有人能解释发生了什么事,我将不胜感激。
下面是代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #include <utility> #include <iostream> #include <vector> #include <string> int main ( ) { std::string s ="abc"; // 1 ok std::pair < std::string, int > a = std::make_pair ( s, 7 ); // 2 error on the next line std::pair < std::string, int > b = std::make_pair < std::string, int > ( s, 7 ); // 3 ok std::pair < std::string, int > d = std::pair < std::string, int > ( s, 7 ); return 0; } |
我理解make_pair的意思是用作(1)情况(如果我指定类型,那么我也可以使用(3)),但我不理解为什么它在这种情况下会失败。
准确的误差是:
test.cpp: In function ‘int main()’:
test.cpp:11:83: error: no matching function for call to ‘make_pair(std::string&, int)’
test.cpp:11:83: note: candidate is:
In file included from /gcc4.7/usr/local/lib/gcc/i686-pc-linux-gnu/4.7.0/../../../../include/c++/4.7.0/utility:72:0,
from test.cpp:1:
/gcc4.7/usr/local/lib/gcc/i686-pc-linux-gnu/4.7.0/../../../../include/c++/4.7.0/bits/stl_pair.h:274:5:
note: template constexpr std::pair::__type, typename
std::__decay_and_strip<_T2>::__type> std::make_pair(_T1&&, _T2&&)
/gcc4.7/usr/local/lib/gcc/i686-pc-linux-gnu/4.7.0/../../../../include/c++/4.7.0/bits/stl_pair.h:274:5:
note: template argument deduction/substitution failed:
test.cpp:11:83: note: cannot convert ‘s’ (type ‘std::string {aka std::basic_string}’) to type ‘std::basic_string&&’
同样,这里的问题是"发生了什么事?"我知道我可以通过删除模板规范来解决这个问题,但我只是想知道在这里什么地方失败了。事先谢谢。
编辑:
- G++4.4编译这段代码没有问题。
- 删除- STD= C++ 11也用代码编译,没有问题。
这不是使用
C++ 11 EDOCX1×0的两个参数是EDCOX1,2,EDCX1,3,EDCX1,4,EDCX1,5是模板类型参数。实际上,它看起来像这样(忽略返回类型):
1 2 | template <typename T, typename U> [return type] make_pair(T&& argT, U&& argU); |
当调用
1 | [return type] make_pair(std::string&& argT, int&& argU); |
注意,这两种参数类型都是右值引用。因此,它们只能绑定到rvalues。对于您传递的第二个参数
那么,当您没有明确指定模板参数列表中的
不管
在您的示例中,我们进行调用:
1 | make_pair(s, 7) |
这里,
为了将左值
将
这些新的语言特性有很多微妙之处,但是如果您遵循一个简单的规则,这很容易:
If a template argument can be deduced from the function arguments, let it be deduced. Don't explicitly provide the argument unless you absolutely must.
Let the compiler do the hard work, and 99.9% of the time it'll be exactly what you wanted anyway. When it isn't what you wanted, you'll usually get a compilation error which is easy to identify and fix.