Here is a toy code to show what I hope it to work like:
int func_invk_lr(int& a) {
cout << "call left" << endl;
return a;
}
int func_invk_lr(int&& a) {
cout << "call right" << endl;
return a;
}
template<typename T>
void call_invk_lr(T&& a) {
std::invoke(func_invk_lr, a); // error: no matching function for call to ‘invoke(<unresolved overloaded function type>, int&)’
std::invoke(func_invk_lr, std::forward<T>(a)); // error: no matching function for call to ‘invoke(<unresolved overloaded function type>, int&)’
}
int main() {
int a = 1;
std::invoke(func_invk_lr, a); // error: no matching function for call to ‘invoke(<unresolved overloaded function type>, int&)’
std::invoke(func_invk_lr, 1); // error: no matching function for call to ‘invoke(<unresolved overloaded function type>, int)’
call_invk_lr(a);
call_invk_lr(1);
}
Here are two things that I am confused:
1. can std::invoke
indentify left or right args and call different functions accordingly?
2. if std::invoke
can work as expected, do we still need std::forward
to pass args in terms of template functions T&&
?
It can do that if you use lambda, std::forward
is required of course:
#include <functional>
#include <iostream>
#include <utility>
void func_invk_lr(int& a) { std::cout << "call left\n"; }
void func_invk_lr(int&& a) { std::cout << "call right\n"; }
template <typename T>
void call_invk_lr(T&& a) {
std::invoke([](auto&& a) { func_invk_lr(std::forward<decltype(a)>(a)); },
std::forward<decltype(a)>(a));
}
int main() {
int a = 1;
std::invoke([](auto&& a) { func_invk_lr(std::forward<decltype(a)>(a)); }, a);
std::invoke([](auto&& a) { func_invk_lr(std::forward<decltype(a)>(a)); }, 1);
call_invk_lr(a);
call_invk_lr(1);
}
// call left
// call right
// call left
// call right
Or a callable
#include <functional>
#include <iostream>
struct func_invk_lr {
void operator()(int& a) { std::cout << "call left\n"; }
void operator()(int&& a) { std::cout << "call right\n"; }
};
int main() {
int a = 1;
std::invoke(func_invk_lr{}, a);
std::invoke(func_invk_lr{}, 1);
}
// call left
// call right