С++ 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’

код:

  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 }

Примечание: Похоже, компилятор оценивает запятые в строке 27, как здесь: http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=/com.ibm.xlcpp8l.doc/language/ref/co.htm

изменить Хорошо, я понимаю проблему, как объяснил Алан. Теперь, для дополнительных мнимых точек, может кто-нибудь объяснить, как компилятор (g++) пришел с сообщением об ошибке, которое он дал?

Ответы

Ответ 1

m_bar - это ссылка, поэтому вы не можете ее построить.

Как отмечали другие, вы можете инициализировать ссылки с объектом, на который он ссылается, но вы не можете создать его, как вы пытаетесь сделать.

Измените строку 30 на

const Bar m_bar

и он будет компилироваться/запускаться правильно.

Ответ 2

m_bar объявляется как "ссылка на константу" и поэтому не может быть создан с помощью конструктора, который вы предоставили.

Подумайте о том, чтобы сделать m_bar членом или передать предварительно сконструированный объект Bar в конструктор.

Ответ 3

Вы можете увидеть проблему более четко в следующем коде:

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

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

который вызывает следующие ошибки с 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'

VС++ 6.0 дает еще большую гномическую ошибку:

 error C2059: syntax error : 'constant'

Проще говоря, вы не можете инициализировать такие ссылки.

Ответ 4

Хотя этот вопрос старый, для будущих читателей я укажу, что элемент, помеченный как ответ, неверен. Ссылка действительно может быть построена.

В строке инициализации код m_bar(foo, a) пытается использовать (foo,a) как конструктор для m_bar. Ошибка сообщает вам, что foo будет проигнорирован, и вы не можете построить Bar из int a. Следующий правильный синтаксис будет компилировать без ошибок:

m_bar (*new Bar(foo,a))