I simplified my code to the root of the problem:
#define GIVE_ME_ODD_BEHAVIOUR true
#include <iostream>
template<typename T> struct X {
T data;
X() : data(0)
{ std::cout << "X construction @ " << this << std::endl; }
template<typename TT>
X(const X<TT> & other) : data(other.data)
{ std::cout << "X construction @ " << this << " from " << &other << std::endl; }
~X()
{ std::cout << "X destruction @ " << this << std::endl; }
template<typename TT>
void Copy(const X<TT> & other)
{ std::cout << "X copy @ " << this << " from " << &other << std::endl; }
};
template<typename T>
X<double> XConversion(const X<T> & other)
{
#if GIVE_ME_ODD_BEHAVIOUR
return X<double>(other);
#else
X<double> d;
d.Copy(other);
return d;
#endif
}
int main()
{
X<double> d;
X<int> i;
std::cout << std::endl;
d = XConversion(i);
std::cout << std::endl;
d = XConversion(d);
std::cout << std::endl;
return 0;
}
which at
GIVE_ME_ODD_BEHAVIOUR true
gives the result:
X construction @ 0x23aa70
X construction @ 0x23aa60
X construction @ 0x23aa80 from 0x23aa60
X destruction @ 0x23aa80
X destruction @ 0x23aa90 // never created !!!
X destruction @ 0x23aa60
X destruction @ 0x23aa70
Sounds like an IT problem , but I did define ctor. I see a copy optimization point here, but:
- Why does a copier destroy an object that it has optimized and thus never create?
- How can I guarantee that this will not happen?
Additional Information:
I tried gcc 4.8.1 and C ++ Builder XE3, disable optimization, debug compilation, with the same result.
I tried to delete the template, for example
struct X {
double data
...
X(const X &)
...
};
but with the same result.
One way to solve this problem would be, for example, to make a private cctor and publish only the Copy method. But that would prevent me (anyone) from even returning the object from the function ...
Background:
, . , - . , . , ref . , , ref .