简体   繁体   中英

Why is it an error to construct an unassigned temporary instance of a class with a const char* variable when that class has a const char* constructor?

Why does this code (unassigned temporary variable constructed from a const char* variable):

class A
{
public:
    A(const char*) {}
};

int main()
{
    const char* constCharPointerVariable = "StringLiteral";
    A(constCharPointerVariable);
    return 0;
}

Give these errors?

error C2512: 'A' : no appropriate default constructor available
error C2040: 'constCharPointerVariable' : 'A' differs in levels of indirection from 'const char *'

Whereas this code (assigned temporary variable constructed from a const char* variable):

class A
{
public:
    A(const char*) {}
};

int main()
{
    const char* constCharPointerVariable = "StringLiteral";
    A a(constCharPointerVariable);
    return 0;
}

Gives no errors.

And this code (unassigned temporary variable constructed from a const char* variable static_cast to a const char*):

class A
{
public:
    A(const char*) {}
};

int main()
{
    const char* constCharPointerVariable = "StringLiteral";
    A(static_cast<const char*>(constCharPointerVariable));
    return 0;
}

Gives no errors.

Bonus points if you can provide the section number in the C++ specification that specifies the first code sample to be not allowed.

A(constCharPointerVariable);

This is actually a declaration of a variable of type A named constCharPointerVariable . It does not create a temporary object.

If you used clang, you'd get the more helpful error message:

error: redefinition of 'constCharPointerVariable' with a different type
    A(constCharPointerVariable);
      ^

As a simpler example, the following is invalid because it declares two int objects in the same scope, both named x :

int x(0);
int (x);

As for why the code is parsed this way, you can find the syntax rules for Declarators in §A.7 of C++11. Basically, when you declare a variable, you can enclose its name in any number of parentheses.

Relevant productions include:

  • declarator -> ptr-declarator
  • ptr-declarator -> noptr-declarator | declarator-id
  • noptr-declarator -> ( ptr-declarator )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM