【问题标题】:Compile error on constructor using pointer to constant c-string使用指向常量 c 字符串的指针在构造函数上编译错误
【发布时间】:2025-12-24 05:00:11
【问题描述】:

谁能解释一下为什么我可以编译并运行它

    T t1( T2( "TEST") );
    t1.print();

但不是这个

    const char * TEST_STRING = "TEST";
    T t1( T2( TEST_STRING ) );
    t1.print();

第二块显示

错误:在‘t1’中请求成员‘print’,它是非类类型‘T(T2)’

类如下

class T2 {
public:
    T2( const char * str ) {
        m_str = str;
    }

    void test() const {
        cout << "t2 test" << m_str << endl;
    }
private:
    const char * m_str;
};

class T {
public:
    T( const T2 & t2 ) {
        t2.test();
    }

    void print() {
        cout << "t print " << endl;
    }
};

我的 g++ 版本是

g++ (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609

谢谢

【问题讨论】:

  • 查找“最令人头疼的解析”。
  • 这是“最令人头疼的解析”,快速修复将 (and ) 更改为 { and }
  • 谢谢。 @RichardCritten 如果我的编译器不支持初始化列表,我应该如何解决这个问题?只需先创建 T2 然后将其传递给 t1 构造函数,例如 const char * TEST_STRING = "TEST"; T2 t2(TEST_STRING); T t1(t2);
  • 另一种解决方法:T t1( static_cast&lt;T2&gt;( TEST_STRING ) );
  • 或者只是:T t1(( T2(TEST_STRING) ));(在声明符周围允许使用额外的括号,但在完整的函数参数周围不允许使用,因此这不可能意味着函数声明。)

标签: c++ constructor compiler-errors most-vexing-parse


【解决方案1】:

感谢immibisRichard Crittenascheplerwiki的所有cmets

问题是因为

T t1( T2( TEST_STRING ) );

可以解释为

  1. 以 T2 作为参数并返回 T 的函数名 t1 的函数声明
  2. 类 T 的 t1 的变量定义,使用类 T2 的匿名实例初始化。

它被解释为函数声明。

两个可能的干净修复,来自aschepler

另一种解决方法:T t1( static_cast&lt;T2&gt;( TEST_STRING ) );

或者只是:T t1(( T2(TEST_STRING) ));(允许使用额外的括号 围绕一个声明符,而不是围绕一个完整的函数参数,所以 不可能是函数声明。)

【讨论】: