
#include <type_traits> #include <functional> //0 template<class R, class... Args> struct function_traits{}; //1 template<class R, class... Args> struct function_traits<std::function<R(Args...)>> : function_traits<R(Args...)>{ static_assert(true, "std::function"); }; //2 template<class Callable> struct function_traits : function_traits<decltype(&Callable::operator())> { static_assert(true, "Callable"); }; int main(void) { std::function<void()> f0; function_traits<decltype(f0)> f1; return 0; } 希望 24 行的模板推导先匹配 1 再 匹配到 0.
实际上先匹配到 1,然后匹配到 2, 然后就推导失败了。
编译器 MSVC 2017.
1 after1990s OP |
2 geelaw 2019-01-02 14:57:15 +08:00 // 0 的正确写法 template <typename T> struct function_traits; template <typename TReturn, typename...TArgs> struct function_traits<TReturn(TArgs...)> { }; 另外 // 2 是不能成功的,因为 instance member function pointer 和 function pointer 完全不同。 |
3 wutiantong 2019-01-02 15:01:32 +08:00 你这代码贴的不对吧,2 没有正确的写成 0 的 specialization |
4 wutiantong 2019-01-02 15:05:06 +08:00 这样写可能更接近你想要的效果: //0 template<class Callable> struct function_traits { static_assert(true, "Callable"); }; //1 template<class R, class... Args> struct function_traits<std::function<R(Args...)>> { static_assert(true, "std::function"); }; |
5 GeruzoniAnsasu 2019-01-02 16:12:16 +08:00 厄…… 另外 我怎么记得 std::function 是没法构造的,不能 trait 出 type 再重新构造一个,只能 move 定义出来的那个 因为就算得到 std::function 的 type,也是没有绑定函数体的,会报 bad_alloc 还是啥 |
6 wutiantong 2019-01-02 16:25:58 +08:00 @GeruzoniAnsasu 你记混了,是 lambda 不能那样干, std::function default construct to a empty function, means operator bool() give false |
7 after1990s OP @wutiantong 感谢,我已经测试成功了。2 是给 lambda 准备的 function_traits,不能删除。 |
8 lrxiao 2019-01-03 00:56:24 +08:00 ?list=PL_AKIMJc4roXJldxjJGtH8PJb4dY6nN1D&t=2001 可以试试这种写法( |
9 FrankHB 2019-01-10 21:33:43 +08:00 ……不清楚要写什么。是要 is_invocable 么? (。。。突然发现命名还真容易撞: https://github.com/FrankHB/YSLib/blob/master/YBase/include/ystdex/function.hpp#L434 ) |