2015-09-16 117 views
2

假设一个算法具有策略FooPolicy。实施此策略的策略类具有静态成员函数foo,但对于其中的一些,foo需要int参数,而对于其他情况则不需要。我试图通过constexpr静态数据成员的手段,以便能够使用具有不同的接口,这些政策类:具有不同接口的策略类

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; 
} 

此代码不能编译。 gcc 4.8.2给出了错误:尽管这是在编译时间FooPolicy::paramFlagtrue称为

no matching function for call to ‘ParamFoo::foo()’

else FooPolicy::foo();

else条款被编译。有没有办法让它工作?

+3

是,提供两个通过例如有条件选择的过载标签调度 – Columbo

+1

你甚至可以免除国旗和SFINAE它。 –

+0

你无法就所有函数的int param = 0参数达成一致吗? –

回答

5

Is there a way to make it work?

一种解决方案是使用无标签的调度:

#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

3

你可以用标志完全分配和使用表达SFINAE:

template <typename FooPolicy> 
struct Alg { 
    template <typename T=FooPolicy> //put FooPolicy in immediate context 
    //SFINAEd out if that call is not valid 
    auto foo() -> decltype(T::foo(),void()) { 
     FooPolicy::foo(); 
    } 

    template <typename T=FooPolicy> 
    auto foo() -> decltype(T::foo(0),void()) { 
     FooPolicy::foo(6); 
    } 
}; 
+0

感谢您提供更好的设计! – AlwaysLearning