символ [N] против символа * - PullRequest
1 голос
/ 31 марта 2011

Может кто-нибудь сказать мне, почему есть ошибка компиляции со следующим кодом?

struct Foo {
  char m_p[8];
  inline operator char *() const { return m_p; }
};

С GCC 4.5 мне выдается сообщение:

ошибка: неверное преобразование из 'const char * 'to' char * '

в то время как компилятор Digital Mars не имеет проблем с ним.

Редактировать: В ответах, перечисленных ниже, упоминается квалификатор const для функции. Что я действительно не понимаю, так это то, почему следующий код не имеет такой проблемы:

struct Foo2 {
  char *m_p;
  inline operator char *() const { return m_p; }
};

Ответы [ 4 ]

6 голосов
/ 31 марта 2011

Поскольку этот оператор является функцией const, this и все его члены (m_p) должны быть константными.Таким образом, тип m_p равен const char[8].Он не может быть неявно преобразован в char*, поскольку const -ness будет потеряна.Преобразование в const char* в порядке.

Вы можете либо заставить его вернуть const char*

 inline operator const char *() const { return m_p; }

, либо удалить квалификатор const

 inline operator char *() { return m_p; }

илипредоставить оба метода.

Цифровой Марс здесь не так.Или, может быть, вам нужно включить некоторые предупреждения.

1 голос
/ 31 марта 2011

Разница между char m_p [8] и char * m_p заключается в том, что первый является частью вашего объекта, и при доступе из метода с использованием const он становится const. Для указателя он указывает куда-то еще, и вы можете вернуть его из квалифицированного метода const, не заставляя его быть константным.

1 голос
/ 31 марта 2011

Поскольку внутри функции (с учетом констант) тип вашего массива равен const char[8], и его нельзя преобразовать в char*, только const char*.

Либо исключите const-квалификацию функции, либо добавьте ее к типу возвращаемого значения. Кроме того, inline здесь избыточно, потому что члены, определенные в определении класса, все равно неявно inline.

0 голосов
/ 31 марта 2011

Ваш оператор помечен как const, поэтому он получает указатель const this. Это означает, что к любому полю struct, к которому вы попытаетесь получить доступ через указатель this, в действительности будет const (потому что к нему обращаются через const -path), поэтому, когда вы делаете return m_p; m_p распадается до const char *, который, в свою очередь, не может быть преобразован в char * (тип возврата оператора), поскольку для удаления модификатора const требуется const_cast.

Короче говоря: если вы хотите, чтобы этот оператор был const, тогда тип возвращаемого значения должен быть const char *, в противном случае у вас возникнет ситуация, когда метод const (=> может быть вызван для const объект) мог бы позволить вызывающей стороне изменять объект (через возвращенный указатель не const), даже если это должно быть запрещено const.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...