How do we test if an expression of a certain type can be invoked with a prvalue?

后端 未结 2 1342
日久生厌
日久生厌 2021-02-05 13:05

With c++17 we have fancy new is_invocable and fancy new prvalues that aren\'t really values.

This permits you to create an object without having to first logically const

相关标签:
2条回答
  • 2021-02-05 13:46

    Is there an alternative, or do we have to invent our own trait to handle this case?

    Yeah, you'd just have to write your own trait that doesn't use declval. Assuming you have std::is_detected lying around (which I know you certainly do):

    template <typename T> T make();
    
    template <typename F, typename... Args>
    using invoke_result_t = decltype(std::declval<F>()(make<Args>()...));
    //                               ^^^^^^^^^^^^^     ^^^^^
    
    template <typename F, typename... Args>
    using is_invocable = std::is_detected<invoke_result_t, F, Args...>;
    

    This way, std::is_invocable<decltype(f), no_move> is false_type, but is_invocable<decltype(f), no_move)> is true_type.

    I intentionally use declval<F>() for the function instead of make so as to allow using decltype(f) here. Really, invoke_result_t should be more complicated, and "do the right thing" for pointers to members, etc. But this is at least a simple approximation that indicates the viability of this approach.

    0 讨论(0)
  • 2021-02-05 13:47

    You are misusing the Invocable concept. This concept means nothing more than the ability to use std::invoke on the given function and the provided arguments.

    You can't do std::invoke(f, no_move(1)), as this would provoke a copy/move of the forwarded argument. It is impossible for a prvalue to be used as a parameter through a forwarded call like invoke. You can pass a prvalue to the forwarding call, but the eventual call to the given function will get an xvalue.

    This is a good reason to avoid using immobile types as value parameters in functions. Take them by const& instead.

    C++ does not have a type trait to see if a function can be called with specific parameters in the way that you want.

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