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;
}
source to share
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.
source to share
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
-
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
source to share