Reputation: 3388
I have a class template:
template<int a, int b>
class foo {
};
I only want to instantiate it when a + b == 10
.
Could I make this possible using std::enable_if
?
Furthermore, if I have a data member in class foo
:
template<int a, int b>
class foo {
int c;
};
I only want to have c
when a == 5
.
How do I do that using std::enable_if
?
Is this one the correct case to use std::enable_if
?
Upvotes: 3
Views: 3611
Reputation: 13752
You can achieve that simply by adding requires
to the template:
template<int a, int b> requires (a + b == 10)
struct foo {
int c;
};
int main() {
foo<3, 7> ok;
// foo<3, 8> doesnt_compile;
}
The requires
clause gets a constant expression
that evaluates to true
or false
deciding thus whether to consider this as a proper match, if the requires clause is true, or ignore it otherwise.
Code: https://godbolt.org/z/yHh4Et
Upvotes: 5
Reputation: 171263
Simple, just don't use enable_if
template<bool Ten>
struct Base
{
int c;
};
template<>
struct Base<false>
{ };
template<int a, int b>
struct foo : Base<a+b == 10>
{
};
Upvotes: 3
Reputation:
template<int a, int b, typename T = typename std::enable_if<a + b == 10>::type>
class foo {
};
This should do the job; just make sure you never explicitly provide the third template parameter when instantiating the template.
As others mentioned, static_assert
is a much better fit.
Upvotes: 13
Reputation: 1897
I guess you can use static_assert better to enforce that constraint instead of enable_if
template<int a, int b>
class foo {
static_assert(a+b==10, "a+b is not 10");
};
int main()
{
foo<5,5> f; // will compile
foo<1,5> f; // will fail to compile with error: a+b is not 10
return 0;
}
enable_if is primarily used to conditionally remove functions and classes from overload resolution based on type traits and to provide separate function overloads and specializations for different type traits.
Upvotes: 12