«Самый важный констант» против auto_ptr: почему код не компилируется?

Следующий код не компилируется в Visual C ++ 2008 или 2010:

#include <memory>

struct A {};

std::auto_ptr<A> foo()  { return std::auto_ptr<A>(new A); }
const std::auto_ptr<A> bar()  { return std::auto_ptr<A>(new A); }

int main()
{
const std::auto_ptr<A> & a = foo(); // most important const

const std::auto_ptr<A> & b = bar(); // error C2558:
// class 'std::auto_ptr<_Ty>' :
// no copy constructor available or copy
// constructor is declared 'explicit'

bar(); // No error?
}

Я ожидал, что «самая важная константа» будет применена к переменной «b», и все же он не компилируется, и по какой-то причине компилятор запрашивает конструктор копирования (что удивляет меня, так как здесь не должно быть никаких копий) , Автономный вызов bar() работает нормально, что означает, я думаю, это действительно инициализация b это проблема.

Это ошибка компилятора или настоящая ошибка компиляции, описанная в стандарте?

(возможно, это было запрещено в C ++ 98 и разрешено в C ++ 11?)

Примечание. Он компилируется в Visual C ++ 2012, gcc 4.6 и Solaris CC (всех компиляторов …), но не в gcc 3.4 и не в XL C).

6

Решение

В C ++ 03 и C ++ 98 при привязке константной ссылки к rvalue (например, функции, возвращаемой по значению), реализация может привязать ссылку непосредственно к rvalue или может сделать копию rvalue и связать ссылка на эту копию. Как auto_ptrКонструктор копирования принимает неконстантную ссылку, этот второй вариант будет работать только в том случае, если возвращаемое значение не const квалифицированный, но компилятор все еще может попытаться это сделать, даже если это не сработает.

В C ++ 11 эти дополнительные копии не разрешены, и реализация должна привязываться непосредственно к rvalue, если преобразование не требуется.

Смотрите также здесь.

13

Другие решения

До C ++ 11, по крайней мере, стандарт требовал, чтобы объект
копируемый в этом контексте. В конце концов, семантика:

T const& t = f();

, где f возвращает T по значению это:

T tmp = f();
T const& t = tmp;

Который требует конструктора копирования.

В случае std::auto_ptrпроблема, которую вы видите
является то, что конструктор копирования определен как неконстантный
ссылка, что означает, что вы не можете скопировать временный. Немного
компиляторы (например, Microsoft) не применяют это, что означает, что
Ваш код может работать с ними, но это в корне незаконно.

Реальный вопрос заключается в том, почему вы используете ссылки здесь. Вы
нужна локальная переменная так или иначе; только ссылка
вводит дополнительный слой косвенности.

1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector