C++11 auto: что делать, если он получает постоянную ссылку?


пожалуйста, взгляните на следующий простой код:

class Foo
{
public:
  Foo(){}
  ~Foo(){}

  Foo(const Foo&){}
  Foo& operator=(const Foo&) { return *this; }
};

static Foo g_temp;
const Foo& GetFoo() { return g_temp; }

Я пытался использовать auto такой:

auto my_foo = GetFoo();

Я ожидал, что my_foo будет постоянной ссылкой на Foo, который является возвращаемым типом функции. Однако, тип auto - это Foo, а не ссылкой. Кроме того, my_foo создается путем копирования g_temp. Это поведение не так очевидно для меня.

чтобы получить ссылку на Foo, мне нужно напишите вот так:

const auto& my_foo2 = GetFoo();
      auto& my_foo3 = GetFoo();

вопрос: почему auto вывести возвращаемый тип GetFoo как объект, а не ссылка?

1 66

1 ответ:

читать эту статью: появление и исчезновение запоров В C++


тип вычета для автоматических переменных в C++0x по существу такой же, как для параметров шаблона. (Насколько я знаю, Единственная разница между ними заключается в том, что тип автоматических переменных может быть выведен из списки инициализации, в то время как типы параметров шаблона не может быть.) Поэтому каждое из следующих объявлений объявляет переменные типа инт (не константный инт):

auto a1 = i;
auto a2 = ci;
auto a3 = *pci;
auto a4 = pcs->i;

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

template<typename T>
void f(T& p);

int i;
const int ci = 0;
const int *pci = &i;

f(i);               // as before, calls f<int>, i.e., T is int
f(ci);              // now calls f<const int>, i.e., T is const int
f(*pci);            // also calls f<const int>, i.e., T is const int

это поведение является старой новостью, применяясь как к C++98, так и C++03. Соответствующее поведение для автоматических переменных, конечно, новое C++0x:

auto& a1 = i;       // a1 is of type int&
auto& a2 = ci;      // a2 is of type const int&
auto& a3 = *pci;    // a3 is also of type const int&
auto& a4 = pcs->i;  // a4 is of type const int&, too

поскольку вы можете сохранить CV-квалификатор, если тип является ссылкой или указателем, вы можете сделать:

auto& my_foo2 = GetFoo();

вместо того, чтобы указывать его как const (то же самое для volatile).

Edit: а почему auto выводит возвращаемый тип GetFoo() в качестве значения вместо ссылки (что было вашим главным вопросом, Извините), рассмотрим это:

const Foo my_foo = GetFoo();

выше будет создана копия, так как my_foo - это ценность. Если auto должны были вернуть ссылку lvalue, выше не было бы возможно.