I'm a bit confused about partial template specialization... I have some code that depends on an arithmetic data type T, and on a small integer DIM. I want to be able to specify different class methods for different values of DIM. The impossibility of using partial template specialization led me to explore enable_if. It's exactly what I needed... except I want it to return a number and not a type. How can I do that? The following code should illustrate what I want.
#include <stdio.h>
#include <iostream>
#include <type_traits>
template <typename T, int DIM>
class foo{
public:
T function();
};
template <typename T, int DIM>
T foo<T, std::enable_if<DIM == 1>::value>::function(){
// do something
return 1.0;
}
template <typename T, int DIM>
T foo<T, std::enable_if<DIM == 2>::value>::function(){
// do something else
return 2342.0;
}
int main(){
foo<int, 1> object;
int ak = object.function();
std::cout << ak << "\n";
return 0;
}
You can totally do what you want with enable_if
, just remember, the substitution has to fail when the condition is false, so you must call type
to ensure the substitution fails when specializing for various conditions.
#include <stdio.h>
#include <iostream>
#include <type_traits>
template <typename T, int DIM>
class foo
{
public:
template <int D = DIM>
typename std::enable_if<D == 1, T>::type
function()
{
// do something
return 1.0;
}
template <int D = DIM>
typename std::enable_if<D == 2, T>::type
function()
{
// do something else
return 2342.0;
}
};
int main(){
foo<int, 1> object;
int ak = object.function();
std::cout << ak << "\n";
return 0;
}
For simple scenarios, like the one above (where you check a specific value, rather than a range of values), you can also use partial specialization. But if you would like to specialize, say, for all values from 1-50
, another for 51-200
, and then a generic fallthrough, enable_if
works great.
You can also use enable_if
in the template signature. Just a quick example.
#include <stdio.h>
#include <iostream>
#include <type_traits>
template <typename T, int DIM>
class foo
{
public:
template <int D = DIM, typename std::enable_if<D == 1, void>::type* = nullptr>
T function()
{
// do something
return 1.0;
}
template <int D = DIM, typename std::enable_if<D == 2, void>::type* = nullptr>
T function()
{
// do something else
return 2342.0;
}
};
int main(){
foo<int, 1> object;
int ak = object.function();
std::cout << ak << "\n";
return 0;
}