Ответ 1
Сначала сообщите, что проблема не связана явно с decltype (auto), так как вы получите почти такой же результат, если функция вернет Counter & в явном виде.
Вы можете рассмотреть следующий код:
typedef std::vector<int> Type;
class DataContainer {
public:
DataContainer() : data(Type(1024, 0)) {}
const Type& getData() const { return data; }
private:
const Type data;
};
const Type& returnLocalRef()
{
DataContainer container;
const Type& data = container.getData();
return data; // o! returning a ref to local - no warning for most compilers
}
Хотя возвращается локальная ссылка, компилятор не дает предупреждения ни в VS2015, ни в gcc48 (с -Wall). Однако, если вы удалили ссылку из const Type & datastrong > , компилятор сразу поймает проблему. Должны ли вы считать такое поведение ошибкой? Спорно.
Основной задачей Compier является компиляция кода. Он предупреждает разработчика о некоторых очевидных проблемах, но в большинстве случаев он не будет делать более глубокого анализа логики программы (время компиляции будет страдать). Это то, что инструменты статического анализа кода разработаны и должны использоваться для.
Описанный случай можно считать простым примером, но одного уровня косвенности достаточно, чтобы "обмануть" компилятор. Поскольку для проверки этого компилятор должен будет проверить, что фактически возвращается из метода getData.
Создание простой модификации:
Type globalData;
...
const Type& getData() const { return globalData; }
сделает ссылку, возвращенную из функции returnLocalRef действительной. Следовательно, это можно рассматривать как компромисс между компилятором между сложностью анализа и эффективностью времени.