C++ 模板匹配失败的问题

2019-01-02 14:51:51 +08:00
 after1990s
#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.

2971 次点击
所在节点    C++
9 条回复
after1990s
2019-01-02 14:54:20 +08:00
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 完全不同。
wutiantong
2019-01-02 15:01:32 +08:00
你这代码贴的不对吧,2 没有正确的写成 0 的 specialization
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"); };
GeruzoniAnsasu
2019-01-02 16:12:16 +08:00
厄…… 另外

我怎么记得 std::function 是没法构造的,不能 trait 出 type 再重新构造一个,只能 move 定义出来的那个
因为就算得到 std::function 的 type,也是没有绑定函数体的,会报 bad_alloc 还是啥
wutiantong
2019-01-02 16:25:58 +08:00
@GeruzoniAnsasu 你记混了,是 lambda 不能那样干,
std::function default construct to a empty function, means operator bool() give false
after1990s
2019-01-02 17:17:01 +08:00
@wutiantong 感谢,我已经测试成功了。2 是给 lambda 准备的 function_traits,不能删除。
lrxiao
2019-01-03 00:56:24 +08:00
<amp-youtube data-videoid="AqDsso3S5fg" layout="responsive" width="480" height="270"></amp-youtube>?list=PL_AKIMJc4roXJldxjJGtH8PJb4dY6nN1D&t=2001
可以试试这种写法(
FrankHB
2019-01-10 21:33:43 +08:00
……不清楚要写什么。是要 is_invocable 么?

(。。。突然发现命名还真容易撞: https://github.com/FrankHB/YSLib/blob/master/YBase/include/ystdex/function.hpp#L434

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/523111

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX