Зачем здесь "const": VS C2664 - PullRequest
       24

Зачем здесь "const": VS C2664

1 голос
/ 21 апреля 2011

Я копирую код с MSDN

В нем говорится, что «В Visual C ++ 2005 компилятор теперь применяет стандартные требования C ++ для применения const. В следующем примере создается C2664».

// C2664d.cpp
// C2664 expected
#include <windows.h>

void func1(LPCSTR &s)
{

}

void func2(LPSTR &s)
{
   func1(s);
}

int main()
{
   return 0;
}

Зачем мне здесь использовать "const"?

Ответы [ 3 ]

4 голосов
/ 21 апреля 2011

(Эти LPCSTR / LPSTR typenames только запутывают код.)

Проблема, с которой вы столкнулись, может быть выражена следующим кратким образом

char *p = NULL;
const char *&r = p; // ERROR

Этот код делаетне компилировать по той же причине, по которой исходная версия не компилируется: такая ссылочная инициализация недопустима в C ++.В вашем примере та же самая инициализация используется неявно в инициализации параметров функции (при вызове func1 из func2), в то время как в моем примере это делается явно.

Причина, по которой она недопустима, в значительной степени та жеT** -> const T** преобразование недопустимо в C ++ (и в C).Это старый FAQ: http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.17.

В принципе, если бы инициализация в моем примере была допустимой, можно было бы продолжить следующую последовательность операций

const char cc = 0;
r = &cc; // OK. Note: `p` now points to `cc`!
*p = 1; // !!! Attempts to modify `cc` !!!

, означающую, чтоэто позволило бы нам нарушить правила правильности констант без каких-либо «взломов», то есть без использования единственного приведения.Это считается неприемлемым в C ++ (так же как и в C), что является причиной, по которой преобразования типа T ** -> const T ** и инициализации типа T *& -> const T *& не допускаются.

Примечаниетакже, что точно так же, как T** -> const T* const* преобразование является допустимым в C ++ (см. раздел часто задаваемых вопросов), инициализация T** -> const T* const& также допустима

char *p = 0;
const char *const &r = p; // OK
1 голос
/ 21 апреля 2011

LPCSTR определяется как "typedef CONST CHAR * LPCST", а LPSTR определяется как "typedef CHAR * LPCST"

Как видите, LPCSTR является константным, а LPSTR - нет, поэтому два типа различаютсяи, следовательно, вам нужен const в вашем контексте.

1 голос
/ 21 апреля 2011

В этом примере кода C2664 будет сгенерирован, потому что код пытается преобразовать ссылку на указатель в ссылку на указатель const.Это две разные вещи.

Преобразование в константную ссылку на указатель (const LPSTR &) будет разрешено.

...