Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

returning move only types from free function vs member function

Let me brief the actual scenario first :

I have created a class template called error<T> which holds the type T and error related variables.
The constructor is like so

error(T&&,..other_params...)   

and there is a utility function that generates this which is defined as so

template<typename T>
make_error(T&& val_T,..other_params..)
{return error<T>(std::forward<T&&>(val_t),..other_params..);}

i use this type as return type instead of just the type T. basically it just wraps the type with error info.

it has a getter which gets the value of the type contained:

T get()
{ return val_T_int;}

where val_T_int is initalized with the val_t above.
When i use a move only type this get gives an error saying delete copy constructor being used.

Q1. why does it say this?why wont it move construct the value?i.e i have to explicitly use std::move() on the return value.

Q2. if Q1 is not possible then how would i enable such a feature where the user, instead of returning a type would return this error .i could not use boost::optional because it needs the type to be copy constructible?

my compiler : minGW GCC 4.8.2 on windows 7.

for example :

class B //a move only type
{
    B( const B& )=delete;
    B& operator=( const B& ) = delete;
public:
    B( B&& )
    {
        std::cout << "B&&\n";
    }

    B& operator=( B&& )
    {
        std::cout << "B=\n";
            return *this; 
    }
    B(){ std::cout << "B()\n"; }
};

struct error  //the other parts are stripped of for simplicity.
{
    B get()
    {
        return std::move(b);
    }
private :
    B b{};// B is a move only type.
};

error er{};
er.get(); //error:use of deleted function B(const B&)!.

what am i not understanding here?. Thanks for reading.

P.S this is close but i dont understand the reason for the local variable.

this and this also dint help

like image 666
Koushik Shetty Avatar asked Jul 04 '26 06:07

Koushik Shetty


1 Answers

Take a look at the following code. If the get method would move the string out of the member variable, what should be the value of t?

error e = make_error(std::string{"foobar"});
std::string s = e.get();
std::string t = e.get();

You can return a reference to the member variable. It might look as follows:

const T& get() const { return val_T_int; }

The problem with that solution is, that you can't use it with non-copyable types the following way:

std::unique_ptr<...> result = make_error(...).get();

However, you can use rvalue-references for this to solve this problem. If you declare get in the following way, the function can only be used on temporaries (and explicitly moved objects). So it's fine to move the member variable out of the object.

T get() && { return std::move(val_T_int); }
like image 63
nosid Avatar answered Jul 06 '26 19:07

nosid



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!