Consider the following code:
#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.
}
Tested under GCC 4.5.2
The reason lies in std::pair
sources:
/** 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) { }
Is that behaviour compliant with the C++ standard? For a first sight it looks inconsistent and counterintuitive. Do the other implementations of STL work the same way?
I am not sure that I understand the question, but basically you are asking why two unrelated std::pair
can be implicitly convertible even if the instantiating types are not implicitly convertible. That is, why the implicitly convertible property of the instantiating types does not propagate to the pair.
The standard does not provide explicit assignment operators for the std::pair
template, which means that it will use the implicitly generated assignment operator. To be able to assign pairs of convertible types, it relies on a templated constructor that allows an implicit conversion from std::pair<A,B>
to std::pair<C,D>
, the behavior of which is defined in §20.2.2 [lib.pairs]/4
template<class U, class V> pair(const pair<U, V> &p);
Effects: Initializes members from the corresponding members of the argument, performing implicit con- versions as needed.
The standard seems to only require the implementation to use implicit conversions, and in this particular implementation the conversion is actually explicit, which seems to contradict the wording of the standard.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With