问题在于隐式转换。不是从int 到
std::vector<int>;那是行不通的,因为涉及的构造函数
声明了explicit,因此不能用于隐式
转换。隐式转换是从std::pair<int, int> 到
std::pair<int, std::vector<int> >。这使用派生的构造函数
来自模板:template <typename U1, typename U2> std::pair(
std::pair<U1, U2> const& ),这不是隐含的。和定义
这个构造函数是:
template <typename T1, typename T2>
template <typename U1, typename U2>
std::pair<T1, T2>::std::pair( std::pair<U1, U2> const& other )
: first( other.first )
, second( other.second )
{
}
(这并不是标准的具体规定。但是
C++03 中的规范不允许做太多其他事情。在 C++11 中,有很多
额外的行李,以便在可能的情况下可以移动构建物品,
但我认为最终的效果是一样的。)
请注意,在此构造函数中,有一个显式调用
构造函数,而不是隐式转换。所以对于隐式
pair 的转换工作,这两种类型就足够了
显式可转换。
就个人而言,我怀疑这是最初的意图。我怀疑,在
事实上,std::pair 周围的大部分语言都被冻结了
在 explicit 被添加到语言之前,所以没有问题。
后来,没有人想过重新讨论这个问题。在 C++11 中,重新审视它
会破坏向后兼容性。所以你会得到一些意想不到的
转化率。
请注意,这不是转发导致
显式转换为隐式。考虑:
std::vector<std::vector<int> > v2D( 5, 10 );
显然,10 不是 std::vector<int>(这是第二个
论据应该是)。但是...在 C++03 中,这与构造函数匹配
模板:
template<typename ForwardIterator, typename ForwardIterator>
std::vector( ForwardIterator begin, ForwardIterator end );
标准对此有一些特殊的语言:
——构造函数
template <class InputIterator>
X(InputIterator f, InputIterator l, const Allocator& a = Allocator())
应具有与以下相同的效果:
X(static_cast<typename X::size_type>(f),
static_cast<typename X::value_type>(l), a)
如果 InputIterator 是整数类型。
并且隐式转换变得显式了。
(请注意,如果没有这种特殊语言,
std::vector<int> v(10, 42);
编译失败:上面的模板构造函数的实例化,
是完全匹配,比std::vector<int>( size_t, int
) 好。委员会认为,需要对第一个
上面的整数到size_t 可能对用户要求太多了。)
C++11 显着改变了这里的措辞,并且:
std::vector<int, std::vector<int>> v2D( 10, 42 );
不再合法。
至少在我所见的情况下,没有这样的更改应用于
std::pair 的构造函数。