Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conversion operator implemented with static_cast

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.

like image 380
Massimiliano Avatar asked Mar 22 '12 09:03

Massimiliano


1 Answers

Looking at [expr.static.cast] in n3337 (first working draft after the Standard):

2/ An lvalue of type “cv1 B,” where B is a class type, can be cast to type “reference to cv2 D,” where D is a class derived (Clause 10) from B, if a valid standard conversion from “pointer to D” to “pointer to B” exists [...]

4/ Otherwise, an expression e can be explicitly converted to a type T using a static_cast of the form static_cast<T>(e) if the declaration T t(e); is well-formed, for some invented temporary variable t [..]

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/.

like image 59
Matthieu M. Avatar answered Nov 09 '22 10:11

Matthieu M.