"Most important constant" versus auto_ptr: why doesn't the code compile?

The following code does not compile on Visual C ++ 2008 and 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? } 

I expected the "most important constant" to apply to the variable "b", and yet it does not compile, and for some reason the compiler asks for the copy constructor (which surprises me since there shouldn't be a copy here). Standalone bar() call works fine, which means that it is really initialization b . This is problem.

Is this a compiler error or a genuine compilation error described in the standard?

(maybe this was forbidden in C ++ 98 and allowed in C ++ 11?)

Note. It compiles on Visual C ++ 2012, gcc 4.6 and on Solaris CC (all compilers ...), but not gcc 3.4, nor XL C)

+6
source share
2 answers

In C ++ 03 and C ++ 98, when linking a const reference to an rvalue (for example, a function that returns a value), an implementation can bind the link directly to rvalue, or it can make a copy of rvalue and bind the link to that copy. Since the copy constructor auto_ptr accepts a non-constant reference, this second choice will work only if the return value of r is not const qualified, but the compiler is still allowed to try to do this, even if it does not work.

In C ++ 11, these additional copies are not allowed, and the implementation should bind directly to the rvalue if conversion is not required.

See also here.

+13
source

Pre C ++ 11, at least the standard required the object to be in this context. In the end, semantics:

 T const& t = f(); 

where f returns the value of T by value:

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

This requires a copy constructor.

In the case of std::auto_ptr problem you see is that the copy constructor is defined as a non-constant reference, which means you cannot copy the temporary one. Some compilers (for example, Microsoft) do not use this, which means that your code can work with them, but this is fundamentally illegal.

The real question is why are you using links here. You need a local variable anyway; only a link introduces an additional layer of indirection.

+1
source

Source: https://habr.com/ru/post/956953/


All Articles