Raf*_*cki 4 c++ constructor explicit standards-compliance
请考虑以下代码:
#include<iostream>
#include<utility>
struct Base
{
int baseint;
};
struct Der1 : Base
{
int der1int;
Der1() : der1int(1) {}
explicit Der1(const Base& a) : Base(a), der1int(1)
{
std::cerr << "cc1" << std::endl;
}
};
struct Der2 : Base
{
int der2int;
Der2() : der2int(2) {}
explicit Der2(const Base& a) : Base(a), der2int(2)
{
std::cerr << "cc2" << std::endl;
}
};
template <typename T, typename U>
struct MyPair
{
T first;
U second;
};
int main()
{
Der1 d1;
Der2 d2;
std::pair<Der1, int> p1;
std::pair<Der2, int> p2;
p1 = p2; // This compiles successfully
MyPair<Der1, int> mp1;
MyPair<Der2, int> mp2;
mp1 = mp2; // This will raise compiler error, as expected.
}
Run Code Online (Sandbox Code Playgroud)
根据GCC 4.5.2进行测试
原因在于std::pair:
/** There is also a templated copy ctor for the @c pair class itself. */
template<class _U1, class _U2>
pair(const pair<_U1, _U2>& __p)
: first(__p.first),
second(__p.second) { }
Run Code Online (Sandbox Code Playgroud)
这种行为是否符合C++标准?对于第一眼看来,它看起来不一致和违反直觉.STL的其他实现是否以相同的方式工作?
我不确定我是否理解这个问题,但基本上你是在问为什么std::pair即使实例化类型不能隐式转换,两个不相关的也可以隐式转换.也就是说,为什么实例化类型的隐式可转换属性不会传播到该对.
该标准没有为std::pair模板提供显式赋值运算符,这意味着它将使用隐式生成的赋值运算符.为了能够分配可转换类型对,它依赖于模板化的构造函数,该构造函数允许从到的隐式转换,其行为在§20.2.2[lib.pairs]/4中定义std::pair<A,B>std::pair<C,D>
template<class U, class V> pair(const pair<U, V> &p);
Run Code Online (Sandbox Code Playgroud)
效果:从参数的相应成员初始化成员,根据需要执行隐式转换.
该标准似乎只要求实现使用隐式转换,并且在此特定实现中,转换实际上是显式的,这似乎与标准的措辞相矛盾.