make_pair 如何知道其参数的类型?
MSVC++“实用程序”标头中 make_pair 的定义是:
template<class _Ty1, class _Ty2> inline pair<_Ty1, _Ty2> make_pair(_Ty1 _Val1, _Ty2 _Val2) { // return pair composed from arguments return (pair<_Ty1, _Ty2>(_Val1, _Val2)); }
我一直使用 make_pair,但没有将参数类型放在尖括号中:
map<string,int> theMap ; theMap.insert( make_pair( "string", 5 ) ) ;
我不应该告诉 make_pair
第一个参数是 std::string
而不是 char*
?
它是怎么知道的?
The definition for make_pair in the MSVC++ "utility" header is:
template<class _Ty1, class _Ty2> inline pair<_Ty1, _Ty2> make_pair(_Ty1 _Val1, _Ty2 _Val2) { // return pair composed from arguments return (pair<_Ty1, _Ty2>(_Val1, _Val2)); }
I use make_pair all the time though without putting the argument types in angle brackets:
map<string,int> theMap ; theMap.insert( make_pair( "string", 5 ) ) ;
Shouldn't I have to tell make_pair
that the first argument is std::string
and not char*
?
How does it know?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
函数模板调用通常可以通过参数推导来避免显式模板参数(即
make_pair<…>
),这是由 C++03 §14.8.2 定义的。摘抄:具体规则有点复杂,但通常只要您只有一种通常足够合格的专业,它就“有效”。
您的示例使用了两步推导和一次隐式转换。
make_pair
返回一个pair
,templatepair::pair(pair const & )
使用U = char*, V = int
启动并执行成员初始化,字符串::字符串(char*)
。Function template calls can usually avoid explicit template arguments (ie
make_pair<…>
) by argument deduction, which is defined by C++03 §14.8.2. Excerpt:The specific rules are a bit complicated, but typically it "just works" as long as you have only one specialization which is generally qualified enough.
Your example uses two steps of deduction and one implicit conversion.
make_pair
returns apair<char const*, int>
,template<class U, classV> pair<string,int>::pair( pair<U,V> const & )
kicks in withU = char*, V = int
and performs member-wise initialization,string::string(char*)
.事实并非如此。 make_pair 生成一对; (或者可能是一对)。
但是,如果您注意到在pair的实现中存在一个模板化的复制构造函数:
这可能以稍微不同的方式实现,但实际上是相同的。由于此构造函数是隐式的,因此编译器会尝试创建对;从你的配对中; - 由于必要的类型是可转换的,所以这是可行的。
It doesn't. make_pair generated a pair<char*,int> (or maybe a pair<char const*,int>).
However, if you'll note in the implementation of pair there's a templated copy constructor:
This may be implemented in slightly different ways but amounts to the same thing. Since this constructor is implicit, the compiler attempts to create pair<std::string,int> out of your pair<char*,int> - since the necessary types are convertible this works.
make_pair()
的存在正是为了可以使用参数类型推导来确定模板参数类型。请参阅这个问题:使用自由函数作为伪函数-利用模板参数推导的构造函数
make_pair()
exists precisely so that argument type deduction can be used to determine the template parameter types.See this SO question: Using free function as pseudo-constructors to exploit template parameter deduction
它依赖于 std::string 的构造函数接受 const char* 的事实。
std::string 的构造函数是否显式并不重要。模板推导类型并使用pair的复制构造函数进行转换。对构造函数是否显式也并不重要。
如果将 std::string 的构造函数转换为:
您会收到此错误:
构造函数如下所示:
复制构造函数如下所示:
It relies on the fact that the constructor of std::string accepts a const char*.
It doesn't matter if this constructor of std::string is explicit or not. The template deducts the type and uses the copy constructor of pair to convert it. It also doesn't matter whether or not the pair constructor is explicit.
If you turn the constructor of std::string into:
you get this error:
The constructor looks like this:
The copy constructor looks like this: