【问题标题】:C++ error - "member initializer expression list treated as compound expression"C++ 错误 - “成员初始化表达式列表被视为复合表达式”
【发布时间】:2009-05-18 10:41:09
【问题描述】:

我遇到了一个我不熟悉的 C++ 编译器错误。可能是一个非常愚蠢的错误,但我不能完全指出它。

错误:

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++)是如何得出它给出的错误消息的吗?

【问题讨论】:

  • g++ 是如何得出它的错误信息的?不知道。 Sun Studio 在第 27 行给出了这个错误:错误:m_bar 的初始化程序太多。它的信息量更大一些。简短的回答是,许多编译器错误消息往往有点难以阅读。
  • 补充说明:之所以出现这个错误,是因为代码试图用 (foo,a) 的构造函数构造一个 Bar 。错误消息告诉您 foo 将被忽略并且它无法将 int a 转换为 Bar。我知道这是一个古老的问题,但是您标记为答案的内容是不正确且具有误导性的。我发布了有关如何单独保留 m_bar 声明并对其进行编译的代码。

标签: c++


【解决方案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'
      

      VC++ 6.0 给出了更多的 gnomic 错误:

       error C2059: syntax error : 'constant'
      

      简单地说,你不能这样初始化引用。

      【讨论】:

        【解决方案4】:

        (编辑:见 cmets) 虽然这个问题很老,但对于未来的读者,我会指出标记为答案的项目是不正确的。确实可以构造引用。

        在初始化行中,代码m_bar(foo, a) 尝试使用(foo,a) 作为m_bar 的构造函数。该错误告诉您foo 将被忽略,并且您无法从int a 构造 Bar。以下正确的语法将无错误地编译:

        m_bar (*new Bar(foo,a))
        

        【讨论】:

        • 标记为正确的答案肯定是正确的!虽然引用可以被构造,但这并不意味着它应该! (尽管您在编译器消息方面处于正确的轨道上,但我会同意您的!)
        • @Tod 我喜欢你的思路(即逗号可以解释为表达式的一部分,而不是两个参数之间的分隔符)——你的编译器可能会给出这样的提示。但是我仍然不能同意您的示例表明“可以构建参考”。您构造的 (new Bar(foo, a)) 是临时的。然后引用只绑定到这个临时的(我们通常不想做的事情)。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-01-07
        • 1970-01-01
        • 2023-03-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多