具有不同接口的策略 类
Policy classes with differing interfaces
假设一个算法有一个策略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
给出错误:
no matching function for call to ‘ParamFoo::foo()’
else FooPolicy::foo();
尽管在编译时已知 FooPolicy::paramFlag
是 true
,但 else
子句仍被编译。有什么办法让它起作用吗?
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();
}
};
您可以完全放弃标志并使用表达式 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);
}
};
假设一个算法有一个策略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
给出错误:
no matching function for call to ‘ParamFoo::foo()’
else FooPolicy::foo();
尽管在编译时已知 FooPolicy::paramFlag
是 true
,但 else
子句仍被编译。有什么办法让它起作用吗?
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();
}
};
您可以完全放弃标志并使用表达式 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);
}
};