0

I've noticed that newer libraries have been deleting the copy constructors from their objects. These objects always require a bit of build-up, so I inevitably have them returned by a function.

But does this mean I'm expected to use pointer semantics after retrieving the object?

Example:
This won't work because the library's object has a deleted copy constructor.

#include <memory>

//fancy library object
struct Foo{
  Foo(){}
  Foo(Foo const& foo)=delete;
};

Foo Create_Foo(){
  Foo f;
  // ... customize f before returning ...
  return f;
}

int main(){

  auto f = Create_Foo();
}

It doesn't seem like I can move the object out of the function:

Foo&& Create_Foo(){
  Foo f;
  // ... customize f before returning ...
  return std::move(f);
}

So I have no choice but to use pointer semantics now?

std::unique_ptr<Foo> Create_Foo(){
  auto f = std::make_unique<Foo>();
  // ... customize f before returning ...
  return f;
}

Is there any way to avoid using pointers,
but still get the constructed object as the result of the function?

I'm not apposed to using pointers, as it's likely the efficient and correct thing to do, but I'm interested in knowing if this is something I'm forced to do when I want the constructed object as the result of the function.

Trevor Hickey
  • 36,288
  • 32
  • 162
  • 271
  • 1
    No copy constructor and no move? What's the library? Does it provide a constructable class as part of API? – Basilevs Dec 13 '15 at 08:20
  • Or do `void Configure_Foo(Foo & f)`. – Don Reba Dec 13 '15 at 08:20
  • @Basilves I've experienced it a lot in boost, but in particular, I'm using clang's lib tooling, and the main object that does all the grunt work is ClangTool. – Trevor Hickey Dec 13 '15 at 08:22
  • 3
    If it's not movable, and you need to do anything more than "run a non-explicit constructor", then you can't return by value. (And returning a local by rvalue reference is broken for all the obvious reasons.) – T.C. Dec 13 '15 at 08:26
  • @Gernot1976: I don't think this is a duplicate. If the type had a move constructor, the std::move wouldn't be needed, but would be (mostly) harmless. I think the problem is the type is not a value type, and yes, you do have to pass it around by pointer. – Martin Bonner supports Monica Dec 13 '15 at 09:27
  • It's a bug in the library. There is no reason for most objects to be unmovable. – n. m. could be an AI Dec 13 '15 at 09:42
  • When RVO became mandatory (corresponding proposal to core language exist), the question will likely disappear. – Tomilov Anatoliy Dec 15 '15 at 17:24

1 Answers1

0

You have declared copy constructor, thus compiler won't declare move constructor.

struct Foo{
    Foo() {}
    Foo(Foo&&) = default;
    Foo(Foo const& foo) = delete;
};

Foo Create_Foo(){
    Foo f;
    // ... customize f before returning ...
    return std::move(f);
}

int main() {
    auto f = Create_Foo();
}
Zereges
  • 5,139
  • 1
  • 25
  • 49
  • In the question, `Foo` is a library object, so simply adding a defaulted move constructor is not as simple. – melak47 Dec 13 '15 at 09:35
  • @melak47 I see, I would like to see the reason why there is no move constructor. – Zereges Dec 13 '15 at 09:40
  • Using `std::move(f)`in the return-statement is unnecessary, and might also disable the more effective [NRVO](http://stackoverflow.com/questions/6531700/when-will-a-c11-compiler-make-rvo-and-nrvo-outperform-move-semantics-and-const) . – Bo Persson Dec 13 '15 at 10:27
  • @BoPersson I am not sure if C++ standard guarantees, that move constructor will be used in this case. – Zereges Dec 13 '15 at 10:42
  • It is guaranteed for C++11, [C++11 Return value optimization or move](http://stackoverflow.com/questions/17473753/c11-return-value-optimization-or-move?lq=1) – Bo Persson Dec 13 '15 at 10:53