SFINAE working in return type but not as template parameter

后端 未结 3 2060
情深已故
情深已故 2020-11-22 14:20

I already used the SFINAE idiom quite a few times and I got used to put my std::enable_if<> in template parameters rather than in return types. However, I

3条回答
  •  佛祖请我去吃肉
    2020-11-22 14:51

    The = ... of the template just gives a default parameter. This is not part of the actual signature which looks like

    template
    auto foo(T a);
    

    for both functions.

    Depending on your needs, the most generic solution for this problem is using tag dispatching.

    struct integral_tag { typedef integral_tag category; };
    struct floating_tag { typedef floating_tag category; };
    
    template  struct foo_tag
    : std::conditional::value, integral_tag,
                        typename std::conditional::value, floating_tag,
                                                   std::false_type>::type>::type {};
    
    template
    T foo_impl(T a, integral_tag) { return a; }
    
    template
    T foo_impl(T a, floating_tag) { return a; }
    
    template 
    T foo(T a)
    {
      static_assert(!std::is_base_of >::value,
                     "T must be either floating point or integral");
      return foo_impl(a, typename foo_tag::category{});
    }
    
    struct bigint {};
    template<> struct foo_tag : integral_tag {};
    
    int main()
    {
      //foo("x"); // produces a nice error message
      foo(1);
      foo(1.5);
      foo(bigint{});
    }
    

提交回复
热议问题