c++c++11policy-based-design

Policy classes with differing interfaces


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?


Solution

  • 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();
        }
    };
    

    DEMO