How to make template rvalue reference parameter ONLY bind to rvalue reference?

前端 未结 5 1967
心在旅途
心在旅途 2020-12-01 08:59

I\'m writing a network library and use move semantics heavily to handle ownership for file descriptors. One of my class wishes to receive file descriptor wrappers of other k

5条回答
  •  有刺的猬
    2020-12-01 09:52

    A simple way is to provide a deleted member which accepts an lvalue reference:

    template void receive_ownership(T&) = delete;
    

    This will always be a better match for an lvalue argument.


    If you have a function that takes several arguments, all of which need to be rvalues, we will need several deleted functions. In this situation, we may prefer to use SFINAE to hide the function from any lvalue arguments.

    One way to do this could be with C++17 and the Concepts TS:

    #include 
    
    template
    void receive_ownership(T&& t)
        requires !std::is_lvalue_reference::value
    {
         // taking file descriptor of t, and clear t
    }
    

    or

    #include 
    
    void receive_ownership(auto&& t)
        requires std::is_rvalue_reference::value
    {
         // taking file descriptor of t, and clear t
    }
    

    Going slightly further, you're able to define a new concept of your own, which may be useful if you want to reuse it, or just for extra clarity:

    #include 
    
    template
    concept bool rvalue = std::is_rvalue_reference::value;
    
    
    void receive_ownership(rvalue&& t)
    {
         // taking file descriptor of t, and clear t
    }
    

    Note: with GCC 6.1, you'll need to pass -fconcepts to the compiler, as it's an extension to C++17 rather than a core part of it.

    Just for completeness, here's my simple test:

    #include 
    int main()
    {
        int a = 0;
        receive_ownership(a);       // error
        receive_ownership(std::move(a)); // okay
    
        const int b = 0;
        receive_ownership(b);       // error
        receive_ownership(std::move(b)); // allowed - but unwise
    }
    

提交回复
热议问题