I ask this question following the issue I raised here.
The point is quite simple. Suppose you have two classes of this kind:
template < class Derived >
class Base {
...
operator const Derived&() const {
return static_cast< const Derived& >(*this);
}
...
};
class Specialization : public Base<Specialization> {
...
};
Then suppose you have a type conversion like this one:
template < class T >
functionCall( const Base<T>& param) {
const T & val(param);
...
}
The question is: what should be the standard conforming behavior of this conversion?
Should it be the same as const T & val(static_cast<const T &> (param) )
or should it recursively iterate until stack overflow? Notice that I obtain the first behavior compiling with GNU g++
and the second compiling with Intel icpc
.
I already tried to peek at the standard (section 5.9 on static_cast and section 12.3 on conversions) but due to my lack of experience I was not able to figure out the answer.
My many thanks in advance to anybody taking the time to help me out with this.
Looking at [expr.static.cast] in n3337 (first working draft after the Standard):
2/ An lvalue of type “cv1
B
,” whereB
is a class type, can be cast to type “reference to cv2D
,” whereD
is a class derived (Clause 10) fromB
, if a valid standard conversion from “pointer toD
” to “pointer toB
” exists [...]4/ Otherwise, an expression
e
can be explicitly converted to a typeT
using astatic_cast
of the formstatic_cast<T>(e)
if the declarationT t(e);
is well-formed, for some invented temporary variablet
[..]
Therefore, I would interpret that gcc's behavior is the correct one, ie the expression:
static_cast<Derived const&>(*this)
should not invoke recursively operator Derived const& () const
.
I deduce this from the presence of the Otherwise keyword which implies an ordering of the rules. The rule 2/
should be tried before the rule 4/
.
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