Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make this boost::enable_if code compile (SFINAE)?

I'm puzzled why the following code that uses boost::enable_if doesn't compile. It checks if type T has a member function hello and calls it if that's the case:

#include <iostream>
#include <boost/utility/enable_if.hpp>
#include <boost/static_assert.hpp>

// Has_hello<T>::value is true if T has a hello function.
template<typename T>
struct has_hello {
  typedef char yes[1];
  typedef char no [2];
  template <typename U> struct type_check;
  template <typename U> static yes &chk(type_check<char[sizeof(&U::hello)]> *);
  template <typename  > static no  &chk(...);
  static const bool value = sizeof(chk<T>(0)) == sizeof(yes);
};

template<typename T>
void doSomething(T const& t,
                 typename boost::enable_if<typename has_hello<T>::value>::type* = 0
                 ) {
  return t.hello();
}

// Would need another doSomething` for types that don't have hello().

struct Foo {
  void hello() const {
    std::cout << "hello" << std::endl;
  }
};

// This check is ok:
BOOST_STATIC_ASSERT(has_hello<Foo>::value);

int main() {
  Foo foo;
  doSomething<Foo>(foo);
}

I'm getting

no matching function for call to ‘doSomething(Foo&)

with gcc 4.4.4.

The static assert is ok, so has_hello<Foo>::value is indeed true. Am I using boost::enable_if wrong?

like image 890
Frank Avatar asked Feb 17 '26 03:02

Frank


1 Answers

First parameter for boost::enable_if must be a type that contains a static bool constant named value. What you need is enable_if_c template (note _c suffix) that takes a non-type bool parameter.

template<typename T>
void doSomething(T const& t,
                 typename boost::enable_if_c<has_hello<T>::value>::type* = 0
                 ) {
  return t.hello();
}

This compiles and runs fine.

Also explained under Paragraph 2 in boost docs.

like image 85
jrok Avatar answered Feb 18 '26 18:02

jrok



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!