Making `std::get` play nice with SFINAE

后端 未结 4 635
南笙
南笙 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 11:17

    std::get is explicitly not SFINAE-friendly, as per [tuple.elem]:

    template 
      constexpr T& get(tuple& t) noexcept;
    // and the other like overloads
    

    Requires: The type T occurs exactly once in Types.... Otherwise, the program is ill-formed.

    std::get is also explicitly not SFINAE-friendly.


    As far as the other questions:

    Is there a reason for std::get not to be SFINAE-friendly?

    Don't know. Typically, this isn't a point that needs to be SFINAE-ed on. So I guess it wasn't considered something that needed to be done. Hard errors are a lot easier to understand than scrolling through a bunch of non-viable candidate options. If you believe there to be compelling reason for std::get to be SFINAE-friendly, you could submit an LWG issue about it.

    Is there a better workaround than what is outlined above?

    Sure. You could write your own SFINAE-friendly verison of get (please note, it uses C++17 fold expression):

    template ::value + ...) == 1, int> = 0>
    constexpr T& my_get(tuple& t) noexcept {
        return std::get(t);
    }
    

    And then do with that as you wish.

提交回复
热议问题