tags:

views:

1939

answers:

3

I'm getting a C++ compiler error which I'm not familiar with. Probably a really stupid mistake, but I can't quite put my finger on it.

Error:

test.cpp:27: error: member initializer expression list treated as compound expression
test.cpp:27: warning: left-hand operand of comma has no effect
test.cpp:27: error: invalid initialization of reference of type ‘const Bar&’ from expression of type ‘int’

Code:

  1 #include <iostream>
  2
  3 class Foo {
  4 public:
  5         Foo(float f) :
  6                 m_f(f)
  7         {}
  8
  9         float m_f;
 10 };
 11
 12 class Bar {
 13 public:
 14         Bar(const Foo& foo, int i) :
 15                 m_foo(foo),
 16                 m_i(i)
 17         {}
 18
 19         const Foo& m_foo;
 20         int m_i;
 21 };
 22
 23
 24 class Baz {
 25 public:
 26         Baz(const Foo& foo, int a) :
 27                 m_bar(foo, a)
 28         {}
 29
 30         const Bar& m_bar;
 31 };
 32
 33 int main(int argc, char *argv[]) {
 34         Foo a(3.14);
 35         Baz b(a, 5.0);
 36
 37         std::cout << b.m_bar.m_i << " " << b.m_bar.m_foo.m_f << std::endl;
 38
 39         return 0;
 40 }

Note: It looks like the compiler is evaluating the commas in line 27 like here: http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=/com.ibm.xlcpp8l.doc/language/ref/co.htm

edit: Okay, I understand the problem as Alan explained it. Now, for extra imaginary points, can someone explain how the compiler (g++) came up with the error message it gave?

+3  A: 

m_bar is declared as a "const reference" and therefore can't be instantiated with the constructor you've supplied.

Consider making m_bar a member, or passing a pre-constructed Bar object to the constructor.

Alan
+5  A: 

m_bar is a reference, so you can't construct one.

As others have noted, you can initialise references with the object it refers to, but you can't construct one like you're trying to do.

Change line 30 to

const Bar m_bar

and it'll compile / run properly.

Glen
+2  A: 

You can see the problem much more clearly in the following code:

struct B {
    B( int a, int x  ) {}
};

int main() {
    const B & b( 1, 2);
}

which produces the following errors with g++:

t.cpp: In function 'int main()':
t.cpp:6: error: initializer expression list treated as compound expression
t.cpp:6: error: invalid initialization of reference of type 'const B&' from expression of type int'

VC++ 6.0 gives the even more gnomic error:

 error C2059: syntax error : 'constant'

Simply put, you can't initialise references like that.

anon