Cannot inititialize std::function implicitly

后端 未结 2 1956
悲哀的现实
悲哀的现实 2021-01-14 18:42

I\'ve written this functor to perform an and operation (&&):

// unary functor; performs \'&&\'
template 
         


        
相关标签:
2条回答
  • 2021-01-14 19:15

    I suggest not abusing std::function and taking normal generic parameters instead. Treat std::function as a type-erased container for callable objects of a particular signature (see https://stackoverflow.com/a/11629125/46642 for more details).

    // unary functor; performs '&&'
    template <typename X, typename Y>
    struct AND
    {
        X x;
        Y y;
    
        template <typename XX, typename YY>
        AND(XX&& xx, YY&& yy) 
                 : x(std::forward<XX>(xx)), y(std::forward<YY>(yy)) {}
    
        template <typename T>
        auto operator() ( const T &arg ) -> decltype(x(arg) && y(arg))
        { return x(arg) && y(arg); }
    };
    
    template <typename T>
    using Decay = typename std::decay<X>::type;
    
    // helper
    template <typename X, typename Y>
    AND<Decay<X>, Decay<Y>> And(X&& xx, Y&& yy)
    {
        return AND<Decay<X>, Decay<Y>>(std::forward<X>(xx), std::forward<Y>(yy));
    }
    
    0 讨论(0)
  • 2021-01-14 19:17

    The problem is that there's no way to deduce T in this context. Let's look at it from the compiler's perspective:

    template <typename T>
    AND<T> And(function<bool (const T&)> xx, function<bool (const T&)> yy)
    
    // Later, invoked as:
    And( is_odd, is_big )
    

    "Hm, no T is specified on the call, I will have to deduce it. What's the argument? is_odd, which is decayed to type int (*)(int). Now, I would have to instantiate std::function<bool (const T&)> for all possible T values and see for which/if any it can be constructed from type int (*)(int). Well, there's infinitely many of them. Not gonna do this."

    It would work if you specified the T tempalte argument explicitly:

    return any_of( first, last, And<int>( is_odd, is_big ) );
    

    Live example


    Note that this holds even if you changed is_odd and is_big to match the function signature exactly (returning bool and taking const int&). It's the deduction that's the problem.

    0 讨论(0)
提交回复
热议问题