Конструктор пустой строки C++

На этот вопрос более чем адекватно ответили, но вы можете найти это полезным: Учебники по указателям на функции . Это по-настоящему всеобъемлющее изложение предмета в пяти главах!

16
задан George 29 May 2009 в 11:18
поделиться

7 ответов

Это очень популярная ошибка. Грамматика C ++ неоднозначна. Одно из правил разрешения двусмысленностей - «если что-то похоже на декларацию, это декларация». В этом случае вместо определения переменной вы объявили прототип функции.

string strA();

эквивалентен

string strA(void);

прототипу функции без аргументов, которая возвращает строку.

Если вы хотите явно вызвать конструктор без аргументов, попробуйте следующее:

string strA=string();

Это не полностью эквивалентно - это означает ' создать временную строку с помощью конструктора no-arg и затем скопировать ее для инициализации переменной strA ', но компилятору разрешено оптимизировать ее и опустить копирование.

РЕДАКТИРОВАТЬ: Вот соответствующий пункт в C ++ FAQ Lite

32
ответ дан 30 November 2019 в 15:18
поделиться

Он рассматривает

string strA();

как объявление функции.

Для использования конструктора по умолчанию:

string strA;
13
ответ дан 30 November 2019 в 15:18
поделиться

В C ++, как и в C, существует правило, согласно которому все, что выглядит как объявление, будет рассматриваться как объявление.

string strA();

выглядит как объявление функции, поэтому обрабатывается как один. Вам необходимо:

string strA;
6
ответ дан 30 November 2019 в 15:18
поделиться

Я не думаю, что в этом случае применимо правило «если это может быть объявление, оно считается объявлением». Поскольку далее обе вещи являются объявлениями

string a;
string a();

Одна - это объявление объекта, а другая - объявление функции. Правило применяется и в других случаях. Например, в этом случае:

string a(string());

В этом случае string () может означать две вещи.

  • Объявление безымянного параметра функции
  • Выражение, создающее построенную по умолчанию строку

Здесь применяется fule, и string () означает то же, что и следующее, названное параметр (имена не имеют значения в параметрах при объявлении функции)

string a(string im_not_relevant());

Если функция принимает в качестве параметра массив или другую функцию, этот параметр распадается на указатель. В случае параметра функции - на указатель на функцию. Таким образом, это эквивалентно следующему, который может показаться более знакомым

string a(string (*im_not_relevant)());

. Но в вашем случае это скорее синтаксис, который мешает. В нем говорится, что следующее - объявление функции. Это никогда не может быть объявлением объекта (даже если это, вероятно, было задумано программистом!)

string a();

Таким образом, в этом контексте в первую очередь нет двусмысленности, и поэтому он объявляет функцию. Поскольку строка имеет конструктор, определенный пользователем, вы можете просто опустить круглые скобки, и эффект останется таким же, как и предполагалось.

говорит, что следующее - объявление функции. Это никогда не может быть объявлением объекта (даже если это, вероятно, было задумано программистом!)

string a();

Таким образом, в этом контексте в первую очередь нет двусмысленности, и поэтому он объявляет функцию. Поскольку строка имеет конструктор, определенный пользователем, вы можете просто опустить круглые скобки, и эффект останется таким же, как и предполагалось.

говорит, что следующее - объявление функции. Это никогда не может быть объявлением объекта (даже если это, вероятно, было задумано программистом!)

string a();

Таким образом, в этом контексте в первую очередь нет двусмысленности, и поэтому он объявляет функцию. Поскольку строка имеет конструктор, определенный пользователем, вы можете просто опустить круглые скобки, и эффект останется таким же, как и предполагалось.

4
ответ дан 30 November 2019 в 15:18
поделиться

tkopec прав в том, почему это не работает. Чтобы ответить на ваш второй вопрос, вот как вы проверяете тип:

template<typename TEST> void Error_() {
   TEST* MakeError = 1;
}

Вызвав Error_ (StrA); , вы получите ошибку компиляции, и ваш компилятор, вероятно, сообщит вам, что это произошло в Error_ > (*) (void)> (std :: basic_string > (*) (void)) Теперь std :: basic_string> - это просто std :: string, так что это действительно означает Error_ (std :: string (*) (void)) . Часть между '<>' повторяется между '()', и это тип strA. В этом случае std :: string (*) (void) .

2
ответ дан 30 November 2019 в 15:18
поделиться

Он печатает 1 , потому что указатели на функции всегда преобразуются в числовые как true .

3
ответ дан 30 November 2019 в 15:18
поделиться

Компилятор интерпретирует string strA () как прототип функции функции, которая принимает пустые аргументы и возвращает объект строкового типа. Если вы хотите создать объект пустой строки, используйте string strA; (без скобок)

1
ответ дан 30 November 2019 в 15:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: