David Doria
David Doria

Reputation: 10273

boost::enable_if_c error: is not a valid type for a template non-type parameter

I want to disallow instantiating a class template (PointCloud) for types with particular type traits. In the following example, I want to only allow types with is_good defined to be used:

#include <boost/core/enable_if.hpp>

class PointType1 {};

class PointType2 {};


template <typename T>
struct is_good
{
  static const bool value = false;
};

template <>
struct is_good<PointType1>
{
  static const bool value = true;
};

template <typename TPoint, typename boost::enable_if_c<is_good<TPoint>::value>::type = 0>
class PointCloud
{
};


int main()
{
  PointCloud<PointType1> pointCloud1;

  //PointCloud<PointType2> pointCloud2;

  return 0;
}

The error is:

error: 'boost::enable_if_c<true, void>::type {aka void}' is not a valid type for a template non-type parameter
   PointCloud<PointType1> pointCloud1;
                        ^

From my understanding, enable_if_c is supposed to define ::type to be TPoint if is_good<TPoint>::value is true. If it is false, then ::type is not defined, so the SFINAE should kick in. I also thought the typename would be indicating that this is indeed a type parameter.

Can anyone explain why this is happening?

Upvotes: 2

Views: 1918

Answers (1)

Praetorian
Praetorian

Reputation: 109219

When you instantiate PointCloud<PointType1>, is_good<TPoint>::value is true and boost::enable_if_c<is_good<TPoint>::value>::type is void.

As the error message says, void is not a valid type for a non-type template parameter.

To fix the error, specify the second type argument for enable_if_c instead of using the default argument void

template <typename TPoint,
          typename boost::enable_if_c<is_good<TPoint>::value, int>::type = 0>
                                                            ^^^^^

Upvotes: 3

Related Questions