Why is this “min” template of cpp-next at fault?

前端 未结 5 724
时光取名叫无心
时光取名叫无心 2021-01-03 21:39

I was reading cpp-next where this min template is presented as an example of how verbose C++ code can be compared to python code

template 

        
5条回答
  •  独厮守ぢ
    2021-01-03 22:12

    What's all the fuss, and why isn't anyone trying the obvious solution, which is perfect forwarding?

    template 
    typename std::enable_if< ! std::is_integral< T >() || ! std::is_integral< U >(),
                             typename std::common_type< T, U >::type >::type
    min(T &&x, U &&y)
        { return x < y ? std::forward< T >( x ) : std::forward< U >( y ); }
    
    template 
    decltype( typename std::enable_if< std::is_integral< T >() && std::is_integral< U >(),
                             decltype( typename std::common_type< T, U >
             ::type{ U( -1 ) } ) >::type{ T( -1 ) } )
    min(T &&x, U &&y)
        { return x < y ? std::forward< T >( x ) : std::forward< U >( y ); }
    

    Now it works just as if you put the expression in the calling function, which is exactly what the user expects (and simply the best thing overall).

    Edit: Now it prohibits dangerous unsigned vs. signed operations, per Howard's paper, by requiring that the conversion from each operand type to the result type be non-narrowing if both operands are of integral type. However, GCC won't compile this, complaining "sorry, unimplemented: mangling constructor." This seems to occur if uniform initialization is used in any way in the function signature.

提交回复
热议问题