Reputation: 10273
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
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