Suppose an algorithm that has a policy FooPolicy
. Policy classes that implement this policy feature a static member function foo
, but, for some of them, foo
takes an int
argument, while for others it does not. I am trying to enable the use of these policy classes with differing interfaces by means of constexpr
static data members:
struct SimpleFoo {
static constexpr bool paramFlag = false;
static void foo() {
std::cout << "In SimpleFoo" << std::endl;
}
};
struct ParamFoo {
static constexpr bool paramFlag = true;
static void foo(int param) {
std::cout << "In ParamFoo " << param << std::endl;
}
};
template <typename FooPolicy>
struct Alg {
void foo() {
if (FooPolicy::paramFlag) FooPolicy::foo(5);
else FooPolicy::foo();
}
};
int main() {
Alg<ParamFoo> alg;
alg.foo();
return 0;
}
This code does not compile. gcc 4.8.2
gives the error:
no matching function for call to ‘ParamFoo::foo()’
else FooPolicy::foo();
The else
clause gets compiled despite the fact that it is known at compile time that FooPolicy::paramFlag
is true
. Is there a way to make it work?
Is there a way to make it work?
One solution is to use tag-dispatching:
#include <type_traits>
template <typename FooPolicy>
struct Alg {
void foo() {
foo(std::integral_constant<bool, FooPolicy::paramFlag>{});
}
private:
void foo(std::true_type) {
FooPolicy::foo(5);
}
void foo(std::false_type) {
FooPolicy::foo();
}
};