我正在试验一些 C++17 功能并遇到了 std::invoke。然后我尝试了这段代码:
#include <iostream>
#include <functional>
void f(int i) { std::cout << "fa "; }
void f(float f) { std::cout << "fb "; }
int main() {
f(0.f);
std::invoke(f, 0.f);
}
我遇到了这些错误:
main.cpp: In function 'int main()':
main.cpp:9:23: error: no matching function for call to 'invoke(<unresolved overloaded function type>, float)'
std::invoke(f, 0.f);
In file included from main.cpp:2:0:
c:/compilers/mingw/lib/gcc/x86_64-w64-mingw32/7.1.0/include/c++/functional:77:5: note: candidate: template<class _Callable, class ... _Args> std::invoke_result_t<_Callable, _Args ...> std::invoke(_Callable&&, _Args&& ...)
invoke(_Callable&& __fn, _Args&&... __args)
^~~~~~
c:/compilers/mingw/lib/gcc/x86_64-w64-mingw32/7.1.0/include/c++/functional:77:5: note: template argument deduction/substitution failed:
main.cpp:9:23: note: couldn't deduce template parameter '_Callable'
std::invoke(f, 0.f);
^
我不是 cpp 专家,这只是为了实验目的。我可能永远不会在这种情况下使用它,但为什么它无法解决函数重载问题?
最佳答案
Edgar 的回答解释了为什么这会给您带来错误,但是有一种比强制转换更好的解决方法,强制转换要求您提供确切的函数签名(可能不知道)。
它涉及将重载解析“提升”到模板化的 operator()
函数中:
std::invoke([](auto&&... xs) -> decltype(auto) { return f(std::forward<decltype(xs)>(xs)...); }, 0.f);
现在这看起来很罗嗦,确实如此,但是您可以使用宏使其更容易接受:
#define LIFT(F) \
([](auto&&... xs) -> decltype(auto) { \
return F(::std::forward<decltype(xs)>(xs)...); \
})
std::invoke(LIFT(f), 0.f);
关于c++ - 为什么 std::invoke 不处理函数重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45505017/