c++constructorcompiler-errorsmost-vexing-parse

Compile error on constructor using pointer to constant c-string


Can somebody explain why I can compile and run this

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

but not this

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

The 2nd blocks show

error: request for member ‘print’ in ‘t1’, which is of non-class type ‘T(T2)’

The classes are as follow

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;
    }
};

my g++ version is

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

Thank you


Solution

  • Thank to all the comments from immibis, Richard Critten, aschepler and wiki

    The problem is because

    T t1( T2( TEST_STRING ) );
    

    can be interpreted as

    1. a function declaration for a function name t1 that take T2 as an argument and return T
    2. a variable definition of t1 of class T, initialized with anonymous instance of class T2.

    and it is interpreted as the function declaration.

    two possible clean fixes, from aschepler

    Another workaround: T t1( static_cast<T2>( TEST_STRING ) );

    Or just: T t1(( T2(TEST_STRING) )); (Extra parentheses are allowed around a declarator, but not around a full function parameter, so that can't possibly mean a function declaration.)