#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 1
@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 ) |