I asked this question earlier where a solution was presented. The solution is great as far as the question is concerned, but now I am confused on how I would define the methods
Here's how SFINAE can actually work with partial specialization:
template<typename T, typename Sfinae = void>
struct Foo {
/* catch-all primary template */
/* or e.g. leave undefined if you don't need it */
};
template<typename T>
struct Foo<T, typename std::enable_if<std::is_base_of<BasePolicy, T>::value>::type> {
/* matches types derived from BasePolicy */
Foo();
};
The definition for that constructor can then be awkwardly introduced with:
template<typename T>
Foo<T, typename std::enable_if<std::is_base_of<BasePolicy, T>::value>::type>::Foo()
{
/* Phew, we're there */
}
If your compiler supports template aliases (it's a C++11 feature) that then you can cut a lot of the verbosity:
template<typename T>
using EnableIfPolicy = typename std::enable_if<std::is_base_of<BasePolicy, T>::value>::type;
// Somewhat nicer:
template<typename T>
struct Foo<T, EnableIfPolicy<T>> {
Foo();
};
template<typename T>
Foo<T, EnableIfPolicy<T>>::Foo() {}
Note: your original answer referred to utilies from Boost, like boost::enable_if_c
and boost::is_base_of
. If you're using that instead of std::enable_if
and std::is_base_of
(which are from C++11), then usage looks like
typename boost::enable_if<boost::is_case_of<BasePolicy, T> >::type
which has the advantage of getting rid of one ::value
.
From the looks of it, you want to do something along the lines of this:
template <typename Policy,
typename = typename std::enable_if<std::is_base_of<BasePolicy, Policy>::value>::type >
struct Foo;
template <typename Policy>
struct Foo<Policy> {
Foo();
};
template <typename Policy>
Foo<Policy>::Foo() {
}
This sneakily takes advantage of the default argument in a few places: don't get confused, there is an implicit void
sitting in several locations.