我正在尝试在std::invoke
周围提供包装器,以进行推导函数类型的工作,即使函数已重载也是如此。(我昨天向related question询问了可变参数和方法指针的版本。)>
[当函数具有一个参数时,此代码(C ++ 17)在正常的重载条件下可以正常工作:
#include <functional> template <typename ReturnType, typename ... Args> using FunctionType = ReturnType (*)(Args...); template <typename S, typename T> auto Invoke (FunctionType<S, T> func, T arg) { return std::invoke(func, arg); } template <typename S, typename T> auto Invoke (FunctionType<S, T&> func, T & arg) { return std::invoke(func, arg); } template <typename S, typename T> auto Invoke (FunctionType<S, const T&> func, const T & arg) { return std::invoke(func, arg); } template <typename S, typename T> auto Invoke (FunctionType<S, T&&> func, T && arg) { return std::invoke(func, std::move(arg)); }
显然,减少更多输入参数的代码膨胀,但这是一个单独的问题。
如果用户的重载仅因const /引用而不同,例如:
#include <iostream> void Foo (int &) { std::cout << "(int &)" << std::endl; } void Foo (const int &) { std::cout << "(const int &)" << std::endl; } void Foo (int &&) { std::cout << "(int &&)" << std::endl; } int main() { int num; Foo(num); Invoke(&Foo, num); std::cout << std::endl; Foo(0); Invoke(&Foo, 0); }
然后
Invoke
用g ++输出错误地推导了该函数:
(int&)(const int&)
(int &&)(const int&)
和clang ++:
(int&)(const int&)
(int &&)(int &&)
(感谢geza指出clang的输出是不同的。
所以Invoke
具有未定义的行为。
我怀疑元编程将是解决此问题的方法。无论如何,是否可以在Invoke
站点正确处理类型推导?
我正试图在std :: invoke周围提供一个包装器,以进行推导函数类型的工作,即使函数被重载也是如此。 (我昨天问了一个有关可变参数和方法的相关问题...