Search code examples
c++c++11g++sfinaeenable-if

enable_if + type template, no SFINAE (enable_if_c without boost ?)


I understand from reading various posts that the following is not supposed to compile.

#include <type_traits>
#include <iostream>

template <bool is_constant> struct A {
  // Need to fix this for g++-4.7.2
  // implicit conversion to int iff is_constant == true statically
  template <class = typename std::enable_if<is_constant>::type>
  constexpr operator int() const {
    return 10;
  }                                             
};

int main()
{
  A<true> a;
  int i = 2 + a;   
  std::cout << i << "\n";

  A<false> b;
  // int i = 2 + a;   // compilation error
}

Still, clang 3.2 accepts this code version and it runs fine. My understanding is that it uses an internal version of enable_if_c under the hood. Now I want to have this compile under gcc which does not accept it. I understand it would be good to have an actual type and use SFINAE as per other posts.

In my case:

  • I am trying to define an operator, so I cannot fuss around with extra parameters that have some default type/value -> it seems I cannot use SFINAE.
  • I cannot use inheritance either because I must keep everything constexpr.
  • I cannot use any boost include in my code (enable_if_c) because of project requirements

Do I have a way out ?


Solution

  • why not to use specialization?

    #include <iostream>
    
    template <bool is_constant>
    struct A {};
    
    template <>
    struct A<true> {
        constexpr operator int() const {
            return 10;
        }
    };
    
    int main()
    {
        A<true> a;
        int i = 2 + a;
        std::cout << i << "\n";
    
        A<false> b;
        // int ii = 2 + b;   // compilation error
    }
    

    this is quite straight forward and cross-compiler approach...