V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
after1990s
V2EX  ›  C++

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

  •  
  •   after1990s ·
    after1990s · 2019-01-02 14:51:51 +08:00 · 2971 次点击
    这是一个创建于 2181 天前的主题,其中的信息可能已经有所发展或是发生改变。
    #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.

    9 条回复    2019-01-10 21:33:43 +08:00
    after1990s
        1
    after1990s  
    OP
       2019-01-02 14:54:20 +08:00
    geelaw
        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 完全不同。
    wutiantong
        3
    wutiantong  
       2019-01-02 15:01:32 +08:00
    你这代码贴的不对吧,2 没有正确的写成 0 的 specialization
    wutiantong
        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"); };
    GeruzoniAnsasu
        5
    GeruzoniAnsasu  
       2019-01-02 16:12:16 +08:00
    厄…… 另外

    我怎么记得 std::function 是没法构造的,不能 trait 出 type 再重新构造一个,只能 move 定义出来的那个
    因为就算得到 std::function 的 type,也是没有绑定函数体的,会报 bad_alloc 还是啥
    wutiantong
        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
    after1990s
        7
    after1990s  
    OP
       2019-01-02 17:17:01 +08:00
    @wutiantong 感谢,我已经测试成功了。2 是给 lambda 准备的 function_traits,不能删除。
    lrxiao
        8
    lrxiao  
       2019-01-03 00:56:24 +08:00
    ?list=PL_AKIMJc4roXJldxjJGtH8PJb4dY6nN1D&t=2001
    可以试试这种写法(
    FrankHB
        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
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2922 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 14:04 · PVG 22:04 · LAX 06:04 · JFK 09:04
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.