Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

auto_ptr in a class not returning from a source function

Tags:

c++

auto-ptr

Consider the following code:

#include<memory>

struct A {
    std::auto_ptr<int> i;
};

A F() {
    A a;
    return a;
}

int main(int argc, char **argv) {
    A a = F();
    return 0;
}

When compiling I receive a compilation error, (see here):

error: no matching function for call to ‘A::A(A)’
     A a = F();
             ^

To my understanding, A::A(A) isn't even allowed to exist, so why is the compiler requesting it? Secondly, why is it not using RVO?


If it is because a std::auto_ptr cannot be returned from a function, why does the following compile and run?

#include<memory>

std::auto_ptr<int> F() {
    std::auto_ptr<int> ap;
    return ap;
}

int main(int argc, char **argv) {
    std::auto_ptr<int> ap = F();
    return 0;
}

I cannot use C++11 in my current work unfortunately, hence the use of auto_ptr.

like image 497
Cramer Avatar asked Nov 10 '22 06:11

Cramer


1 Answers

I tried searching but couldn't find a relevant Q&A, even though I know this is a duplicate. So instead I'm answering instead of voting to close as a duplicate. Apologies.


The reason it needs a copy constructor is because the line:

A a = F();

is really (from the compiler's perspective):

A a(F());

even if copy elision/RVO is used. That is, the compiler does not do:

// This is NOT what the compiler does for A a = F();
A a;
a = F();

Even with copy elision/RVO, A a(F()); won't work. From a C++ standards perspective, the code needs to be legal, whether or not the compiler does copy elision. Copy elision doesn't relax the requirement of needing a copy constructor (even if it doesn't actually use it; it still needs to be there in order to ensure "legality" of the code).

This doesn't work, because std::auto_ptr's copy constructor doesn't take a const reference, so A's copy constructor doesn't exist. F() returns a temporary A, which can only be captured by a const reference, which means that line of code is trying to use a non-existent copy constructor.

like image 98
Cornstalks Avatar answered Nov 15 '22 06:11

Cornstalks