【发布时间】:2010-04-19 22:59:35
【问题描述】:
MSVC++“实用程序”标头中make_pair的定义是:
模板尽管没有将参数类型放在尖括号中,但我一直使用 make_pair:
map我不应该告诉make_pair第一个参数是std::string而不是char*吗?
它是怎么知道的?
【问题讨论】:
MSVC++“实用程序”标头中make_pair的定义是:
模板尽管没有将参数类型放在尖括号中,但我一直使用 make_pair:
map我不应该告诉make_pair第一个参数是std::string而不是char*吗?
它是怎么知道的?
【问题讨论】:
函数模板调用通常可以通过参数推导避免显式模板参数(即make_pair<…>),这是由C++03 §14.8.2 定义的。摘录:
当一个函数模板 专业化被引用,所有 模板参数必须有 价值观。这些值可以是 明确指定,或在某些情况下 案例,由使用推断。
具体规则有点复杂,但通常只要你只有一个通常足够合格的专业,它“就行了”。
您的示例使用了两步推演和一个隐式转换。
make_pair 返回 pair<char const*, int>,template<class U, classV> pair<string,int>::pair( pair<U,V> const & ) 启动U = char*, V = int 并执行成员初始化,string::string(char*)。【讨论】:
make_pair 类型,pair 中的模板化构造函数负责类型转换。
make_pair 弄清楚自己的返回类型。
make_pair如何推导出第一个元素是string,答案是它不是,而不是它是一个“完美的例子”。涉及一个两步过程,第二步是执行转换的一步。我赞成,因为问题的后半部分是准确和正确的。 (可能误导是错误的词和 误导 本身:))。
它没有。 make_pair 生成了一对
但是,如果您注意到在 pair 的实现中有一个模板化的复制构造函数:
template < typename Other1, typename Other2 >
pair(pair<Other1,Other2>& other)
: first(other.first), second(other.second)
{}
这可能以稍微不同的方式实现,但相当于同一件事。由于此构造函数是隐式的,因此编译器会尝试从您的 pair
【讨论】:
make_pair()正好存在,所以可以通过参数类型推导来确定模板参数类型。
看到这个问题:Using free function as pseudo-constructors to exploit template parameter deduction
【讨论】:
它依赖于 std::string 的构造函数接受 const char* 的事实。 std::string 的这个构造函数是否显式都没关系。模板扣除类型,使用pair的拷贝构造函数进行转换。对构造函数是否显式也无关紧要。
如果你把std::string的构造函数变成:
class string
{
public:
string(char* s)
{
}
};
你得到这个错误:
/usr/include/c++/4.3/bits/stl_pair.h: In constructor ‘std::pair<_T1, _T2>::pair(const std::pair<_U1, _U2>&) [with _U1 = const char*, _U2 = int, _T1 = const string, _T2 = int]’:
foo.cpp:27: instantiated from here
/usr/include/c++/4.3/bits/stl_pair.h:106: error: invalid conversion from ‘const char* const’ to ‘char*’
/usr/include/c++/4.3/bits/stl_pair.h:106: error: initializing argument 1 of ‘string::string(char*)’
构造函数如下所示:
template<class _U1, class _U2>
pair(const pair<_U1, _U2>& __p)
: first(__p.first),
second(__p.second) { }
复制构造函数如下所示:
template<class _U1, class _U2>
pair(const pair<_U1, _U2>& __p)
: first(__p.first),
second(__p.second) { }
【讨论】:
X 的复制构造函数采用X& 或X const & 类型的单个参数。模板化构造函数永远不能是复制构造函数。 (也就是说,如果类X 定义了template <typename T> X( T& );,即使X x( f() ); 和f 返回X 匹配模板化的协程函数,编译器将使用隐式生成的复制构造函数而不是显式定义的模板化构造函数。)