Почему ошибочно создавать неназначенный временный экземпляр класса с переменной const char *, когда этот класс имеет конструктор const char *? - PullRequest
1 голос
/ 04 марта 2012

Почему этот код (неназначенная временная переменная, созданная из переменной const char *):

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

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

Дайте эти ошибки?

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

Принимая во внимание, что этот код (назначенная временная переменная, созданная из переменной const char *):

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

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

Не дает ошибок.

И этот код (неназначенная временная переменная, созданная из const char *, переменная static_cast для const char *):

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

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

Не дает ошибок.

Бонусные баллы, если вы можете указать номер раздела в спецификации C ++, в котором указан первый пример кода, который нельзя использовать.

1 Ответ

7 голосов
/ 04 марта 2012
A(constCharPointerVariable);

Это на самом деле объявление переменной типа A с именем constCharPointerVariable.Он не создает временный объект.

Если вы использовали clang, вы получите более полезное сообщение об ошибке:

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

В качестве более простого примера следующее недопустимо, поскольку оно объявляетдва int объекта в одной и той же области, оба названы x:

int x(0);
int (x);

Что касается того, почему код анализируется таким образом, вы можете найти правила синтаксиса для объявлений в §A.7 C++ 11.По сути, когда вы объявляете переменную, вы можете заключить ее имя в любое количество скобок.

Соответствующие продукты включают в себя:

  • декларатор -> декларатор ptr
  • декларатор ptr -> декларатор noptr | идентификатор объявления
  • noptr-декларатор -> ( ptr-декларатор )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...