Lambda is deduced to std::function if template has no variadic arguments

前端 未结 2 1407
有刺的猬
有刺的猬 2021-02-07 22:08
template
void foo(std::function callback)
{}

template
voi         


        
2条回答
  •  后悔当初
    2021-02-07 22:29

    template
    void foo(std::function callback)
    {}
    

    now, foo is foo.

    It does not fully specify ParamT. In fact, there is no way to fully specify ParamT.

    As an incompletely specified template, deduction occurs, and fails. It doesn't try "what if I just assume the pack doesn't go any further".

    You can fix this with:

    template
    void foo(block_deduction> callback)
    {}
    

    where block_deduction looks like:

    template
    struct block_deduction_helper { using type=T; }:
    template
    using block_deduction = typename block_deduction_helper::type;
    

    now deduction is blocked on foo's first argument.

    And your code works.

    Of course, if you pass in a std::function it will no longer auto-deduce arguments.

    Note that deducing the type of a a type erasure type like std::function is usually code smell.

    Replace both with:

    template
    void bar(F callback)
    {}
    

    if you must get arguments, use function traits helpers (there are many on SO). If you just need return value, there are std traits that already work that out.


    In c++17 you can do this:

    tempate
    void bar( std::function f ) {}
    template
    void bar( F f ) {
      std::function std_f = std::move(f);
      bar(std_f);
    }
    

    using the c++17 deduction guides feature.

提交回复
热议问题