Can c++ std::invoke choose appropriate lvalue or rvalue reference arg overload automatically? - Stack Overflow

Here is a toy code to show what I hope it to work like:int func_invk_lr(int& a) {cout << &quo

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&& ?

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&& ?

Share Improve this question edited Mar 6 at 6:41 Raymond Chen 45.2k11 gold badges99 silver badges144 bronze badges asked Mar 6 at 3:16 Zeyu Zhang CNZeyu Zhang CN 1355 bronze badges 3
  • 1 Please decrypt "not working". Is that based on the posted code - error: use of undeclared identifier 'cout', error: use of undeclared identifier 'std'...? – 3CxEZiVlQ Commented Mar 6 at 3:25
  • 3 The name func_invk_lr is ambiguous since it names an overload set. – NathanOliver Commented Mar 6 at 3:26
  • What is a in the first line of main()? – 3CxEZiVlQ Commented Mar 6 at 4:50
Add a comment  | 

1 Answer 1

Reset to default 1

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

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744998287a4605334.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信