Kevin said:
In fact, they are both correct (I think). Attila's answer is what I
would have said. The problem Jim pointed out is a bit more insidious:
C c(B(a));
I don't know the exact rule, but basically because this *could* be
either a function declaration or an object instantiation, the former
wins. It's equivalent to
C c(B a);
With a pair of superfluous parenthesis.
I'm 99.999% sure the statement 'C c(B(a));' is a function declaration
(see: 8.2/1 in ISO 14882:1998).
FWIW, you can disambiguate the interior subexpression 'B(a)' by wrapping
it in parens, e.g.,
C c( (B(a)) );
Now the compiler treats 'B(a)' as an object declaration that uses a
function-style type cast as the initializer (and not a function
declaration with a redundant set of parens around a parameter name).
IOW, 'B(a)' is now considered an invocation of B::B(A&). Consequently,
the surrounding expression - i.e., the declaration of 'c' - is also
treated as an object declaration with a function-style type cast as the
initializer.
Caveat: Making this change to your code introduces another problem.
Specifically, the unnamed, temporary class B object that results from
the invocation of B::B(A&) cannot be bound to a non-const reference. So
the construction of 'c' cannot occur because class C does not have a
suitable constructor - e.g., C::C(B&) cannot be used because B& is a
non-const reference. There are (at least) two fixes for this problem:
1) Modify the existing class C ctor
C(B &) { }
so its reference is const-valued
C(const B &) { }
or,
2) Add a second ctor to class C; one with a suitable const reference
argument:
class C {
C (B &) { }
C (const B &) { }
void f () { }
}