C ++ pass by value / from support function overload

There are 2 overload functions:

MyClass do_something(MyClass param);
const MyClass& do_something(const MyClass& param);

      

Then I do:

MyClass c1 {"c1"};
do_something(c1);  // I want this to be used by value overload
do_something(c1);  // this to be used by reference overload

      

Is there any special way to explicitly indicate that an argument is passed by value or by reference?

For moving semantics there is std::move()

I wonder if there is something like this std::copy()

std::ref

for my case?

PS It shouldn't be used in a real program, just checking separately for the difference in passing arguments returning values ​​and their behavior differently and having all functions with the same name:

// pass by value (copy)
MyClass do_something(MyClass param) {
    cout << "do_something(MyClass param)" << endl;
    param.i = 100;
    return param;
}

// !!! Your normal habit when passing an argument to a function should be to pass by const reference. (thinking in c++)
// pass by reference (reference)
const MyClass& do_something(const MyClass& param) { // doesn't allow to modify the object
    cout << "do_something(MyClass& param)" << endl;
    return param;
}

// pass by move semantic (move)
MyClass&& do_something(MyClass&& param) {
    cout << "do_something(MyClass&& param)" << endl;
    param.name += "__after_do_something(MyClass&& param)";
    param.i = 100;
    return move(param);
}

// pass by pointer (reference)
MyClass* do_something(MyClass* const param) { // allows to modify object, but not pointer (address)
    cout << "do_something(MyClass* const param)" << endl;
    param->i = 100;
    // (*param).i = 100;  // the same as above
    return param;
}

      

+3


source to share


3 answers


You can resolve the ambiguity of the overload by clicking on the appropriate type of the function pointer (this is one of the rare cases where the type of an expression is determined by the external context, rather than inline from within):

struct MyClass { char const* s; };

MyClass do_something(MyClass) { return MyClass(); }
const MyClass& do_something(const MyClass& param) { return param; }

auto main() -> int
{
    MyClass c1 {"c1"};
    static_cast<MyClass(*)(MyClass)>( do_something )( c1 );         // Value overload
    static_cast<MyClass const&(*)(MyClass const&)>( do_something )( c1 );  // Ref overload
}

      



But in practice, you should just name the functions differently, or use arguments or tie-break arguments, i.e. create functions to explicitly select a function.

I would call them differently because they do different things, so this indicates the wrong thing and the trade; for the same name for them.

+1


source


Is there any special way to explicitly indicate that an argument is passed by value or by reference?

No, but there is a workaround.



  • With the template and specialization method, you can explicitly specify which version you want:

    template <typename T>
    T do_something(T);
    
    template<>
    MyClass do_something(MyClass) { std::cout << "value" << std::endl; }
    
    template<>
    const MyClass& do_something(const MyClass&)
    {
        std::cout << "reference" << std::endl;
    }
    
          

    And then call it:

    do_something<MyClass>(c); // value
    do_something<const MyClass&>(c); // reference
    do_something(c); // value
    
          

    Live Demo

  • But it would be simpler / cleaner to create an explicit tag overload:

    struct by_value{};
    struct by_ref{};
    
    MyClass do_something(MyClass, by_value) { std::cout << "value" << std::endl; }
    
    const MyClass& do_something(const MyClass&, by_ref)
    {
        std::cout << "reference" << std::endl;
    }
    
          

    And name it

    do_something(c, by_value{}); // value
    do_something(c, by_ref{}); // reference
    
          

+2


source


Is there any special way to explicitly indicate that an argument is passed by value or by reference?

Yes. If it is not copied (i.e. a remote or private copy constructor), it can only be passed by reference.

-2


source







All Articles