与指定的模板参数配对不能编译
我只是在启用了-std = c ++ 11的情况下玩弄了g ++ 4.7(其中一个较晚的快照)。 我试图编译一些我现有的代码库和一个失败的混淆我的案例。
如果有人能解释发生了什么,我将不胜感激。
这是代码
#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:在函数'int main()'中:test.cpp:11:83:错误:没有用于调用'make_pair(std :: string&,int)'test.cpp:11:83的匹配函数:注意:候选人是:从/gcc4.7/usr/local/lib/gcc/i686-pc-linux-gnu/4.7.0/../../../../include/c++/4.7包含的文件中。 0 / utility:72:0,来自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:can not convert's'(type'std :: string {aka std :: basic_string}')to type '的std :: basic_string的&&'
再次,这里的问题只是“发生了什么?” 我知道我可以通过删除模板规范来解决问题,但我只想知道封面下面的失败。 提前致谢。
编辑:
这不是如何使用std::make_pair
; 你不应该明确指定模板参数。
C ++ 11 std::make_pair
接受两个类型为T&&
和U&&
,其中T
和U
是模板类型参数。 实际上,它看起来像这样(忽略返回类型):
template <typename T, typename U>
[return type] make_pair(T&& argT, U&& argU);
当你调用std::make_pair
并显式地指定模板类型参数时,不会发生任何推论。 相反,类型参数被直接替换为模板声明,从而产生:
[return type] make_pair(std::string&& argT, int&& argU);
请注意,这两种参数类型都是右值引用。 因此,他们只能绑定到右值。 这对于你传递的第二个参数7
来说不是问题,因为这是一个右值表达式。 s
,但是,是一个左值表达式(它不是暂时的,它没有被移动)。 这意味着函数模板与您的参数不匹配,这就是您遇到错误的原因。
那么,为什么当你没有明确指定模板参数列表中的T
和U
时,它会起作用? 简而言之,右值引用参数在模板中是特殊的。 部分由于参考折叠的语言特征,类型A&&
的右值引用参数(其中A
是模板类型参数)可以绑定到任何类型的A
无论A
是左值还是右值,const限定,volatile限定或不合格, A&&
都可以绑定到该对象(当且仅当A
本身是模板参数时)。
在你的例子中,我们打电话:
make_pair(s, 7)
这里, s
是std::string
类型的左值, 7
是int
类型的右值。 由于您没有为函数模板指定模板参数,因此会执行模板参数推导以确定参数是什么。
结合s
,左值,到T&&
,编译器推断T
要std::string&
得到类型的参数std::string& &&
。 虽然没有引用的引用,所以这个“双引用”崩溃成为std::string&
。 s
是一场比赛。
绑定7
到U&&
很简单:编译器可以推导出U
为int
,产生一个int&&
类型的参数,它成功绑定到7
因为它是一个右值。
这些新的语言功能有很多细微之处,但如果遵循一条简单的规则,那就很简单:
如果可以从函数参数中推导出一个模板参数,那么就可以推导出它。 除非你绝对必须,否则不要明确提供论点。
让编译器努力工作,99.9%的时间完全是你想要的。 当它不是你想要的,你通常会得到一个很容易识别和修复的编译错误。
链接地址: http://www.djcxy.com/p/29747.html上一篇: pair with specified template parameters doesn't compile