Подтвердить что ты не робот

Назначения типа "auto" указателя в С++ 11 требуют "*"?

Учитывая, что моя переменная является указателем, если я назначаю ее переменной типа "auto", я могу указать "*"?

std::vector<MyClass> *getVector(); //returns populated vector
//...

std::vector<MyClass> *myvector = getVector();  //assume has n items in it
auto newvar1 = myvector;

// vs:
auto *newvar2 = myvector;

//goal is to behave like this assignment:
std::vector<MyClass> *newvar3 = getVector();

Я немного смущен тем, как этот auto работает в С++ 11 (это новая функция для С++ 11, правда?)

Обновление:. Я пересмотрел выше, чтобы лучше понять, как мой вектор действительно заполняется функцией, и я просто пытаюсь назначить возвращаемый указатель на переменную. Извините за путаницу

4b9b3361

Ответ 1

auto newvar1 = myvector;

// vs:
auto *newvar2 = myvector;

Оба они одинаковы и объявят указатель на std::vector<MyClass> (указывая на случайное местоположение, поскольку myvector неинициализируется в вашем примере и, вероятно, содержит мусор). Таким образом, вы можете использовать любой из них. Я бы предпочел auto var = getVector(), но вы можете пойти на auto* var = getVector(), если считаете, что он подчеркивает намерение (что var является указателем) лучше.

Я должен сказать, что я никогда не мечтал о подобной неопределенности, используя auto. Я думал, что люди просто используют auto и не думают об этом, что является правильным в 99% случаев - необходимость украшать auto чем-то только со ссылками и cv-квалификаторами.

Однако есть небольшая разница между ними при незначительном изменении:

auto newvar1 = myvector, newvar2 = something;

В этом случае newvar2 будет указателем (и что-то тоже должно быть).

auto *newvar1 = myvector, newvar2 = something;

Здесь newvar2 - тип адресата, например. std::vector<MyClass>, и инициализатор должен быть адекватным.

В общем случае, если инициализатор не является скопированным списком инициализаторов, компилятор обрабатывает auto следующим образом:

  • Он создает объявление шаблона искусственной функции с одним аргументом точной формы декларатора, при замене auto на параметр шаблона. Итак, для auto* x = ... он использует

    template <class T> void foo(T*);
    
  • Он пытается разрешить вызов foo(initializer) и смотрит, что выводится для T. Это заменяется вместо auto.

  • Если в объявлении больше деклараций, это делается для всех них. Выведенный T должен быть одинаковым для всех из них...

Ответ 2

auto newvar1 = *myvector;

Это, вероятно, то, что вы хотите, что создает копию фактического вектора. Если вы хотите иметь ссылку вместо записи auto& newvar1 = *myvector; или создать другой указатель на одно и то же векторное использование auto newvar1 = myvector;. Разница с вашей другой попыткой auto *newvar1 = myvector; заключается в том, что последний однажды заставляет myvector иметь тип указателя, поэтому следующий код не работает:

std::vector<int> v1;
auto* v2 = v1; // error: unable to deduce ‘auto*’ from ‘v1’

Ответ 3

Между константой auto и auto* существует, возможно, тонкая разница.

int i;
const auto* p = &i;

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

int i;
const int* p = &i;

тогда как

int i;
const auto p = &i;

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

int i;
const int* const p = &i;

Это имеет следующий эффект:

void test(int a) {
    const auto* p1 = &a;

    *p1 = 7;               // Error
    p1 = nullptr;          // OK

    const auto p2 = &a;

    p2 = 7;                // Error
    p2 = nullptr;          // Error
}