Making `std::get` play nice with SFINAE

后端 未结 4 665
南笙
南笙 2021-02-05 10:20

std::get does not seem to be SFINAE-friendly, as shown by the following test case:

template 
auto foo(C &c) -> declty         


        
4条回答
  •  轮回少年
    2021-02-05 10:59

    Almost no function in STL is SFINAE-friendly, this is the default.

    Maybe it is purely historical. (as in "C++ has all the defaults wrong").

    But perhaps a post-facto justification could be that SFINAE-friendlyness has a cost (e.g. compile time). I don't have proof, but I think it is fair to say that SF-code takes longer to compile because it has to "keep trying" when rejecting alternatives instead of bailing out on the first error. As @Barry said it has also a mental cost because SFINAE is harder to reason about than hard errors. (At least before one has the "concepts" clear.)

    If the user wants SFINAE it can be built (with a lot of effort) on top of non-SFINAE friendly with help of traits.

    For example, one can always write (@Barry wrote the equivalent for std::get)

    template::reference, std::iterator_traits::reference> >
    Out friendly_copy(In first, In last, Out d_last){
       return std::copy(first, last, d_first);
    }
    

    Honestly, I find myself wrapping many STL functions this way, but it is a lot of work to get it right. So, I guess that there is a place for a SFINAE-friendly version of STL. In some sense this is comming if requires are added to the signatures of the current functions. I don't know if this is the plan exactly but it might be a side effect of introducing concepts to the language. I hope so.

提交回复
热议问题