对可变参数使用声明.如何选择正确的功能
Using declaration on variadic args. How to choose the correct function?
我有一个基于策略的设计,其中在一些策略中定义了一些函数foo()
,但在其他策略中没有定义。基类总是继承自某个名为AlwaysBase
的类,该类具有较差的foo()
函数。
我想这样做,如果;"更好";foo()
存在(策略类中的一个(,将始终选择一个。
这里有一些代码:
// logic for determining if a class has a member function (not really related)
template <class> struct sfinae_true: std::true_type{};
template <class T> static auto test_foo(int) -> sfinae_true<decltype(std::declval<T>().foo())>;
template <class> static auto test_foo(long) -> std::false_type;
template <class T> struct has_foo : decltype(test_foo<T>(0)){};
class AlwaysBase{ public: void foo(){ cout << "in AlwaysBase foo()" << endl; } };
class BPolicy{};
class CPolicy{ public: void foo(){ cout << "in Cpolicy foo()" << endl; } };
template<typename T, typename ...Args>
class A: public T, public A<Args...>
{
public:
using std::conditional_t<has_foo<T>::value, T, AlwaysBase>::foo;
};
template<typename T>
class A<T>: public T, public AlwaysBase
{
public:
using std::conditional_t<has_foo<T>::value, T, AlwaysBase>::foo;
};
int main()
{
A<BPolicy> b;
b.foo(); // outputs: In AlwaysBase foo()
A<CPolicy> c;
c.foo(); // outputs: In CPolicy foo()
A<CPolicy, BPolicy> cb;
cb.foo(); // outputs: In CPolicy foo()
A<BPolicy, CPolicy> bc;
bc.foo(); // outputs: In AlwaysBase foo() // I WANT THIS TO OUTPUT!!!!: In CPolicy foo
}
我理解这里发生的事情,当BPolicy
是第一个时,using语句首先在variadic args类中使用,并隐藏在终止基类(即CPolicy::foo(中找到的任何前面的using语句。
我希望在指定策略时,顺序无关紧要,如果策略有一个行列式,则应始终首先选择该行列式,而不是AlwaysBase::foo
。
使用递归。如果允许空列表,这很容易:
// recursive invariant: As<Ts...>::foo is always the foo from the first capable Ts or from AlwaysBase
template<typename... Ts>
class A : public AlwaysBase { // template<> class A<>
public:
// there are no capable Ts
using AlwaysBase::foo;
};
template<typename T, typename... Ts>
class A<T, Ts...> : public T, public A<Ts...> {
public:
// from the A<Ts...> superclass, not AlwaysBase
// try to use T, fall back to Ts, and only then fall back to AlwaysBase
using std::conditional_t<has_foo<T>::value, T, A<Ts...>>::foo;
};
限制到非空列表有点烦人:
template<typename T, typename... Ts>
class A : public T, public A<Ts...> {
public:
using std::conditional_t<has_foo<T>::value, T, A<Ts...>>::foo;
};
template<typename T>
class A<T> : public T, public AlwaysBase {
public:
using std::conditional_t<has_foo<T>::value, T, AlwaysBase>::foo;
};
不过,秩序仍然很重要。如果两个策略提供foo
,则第一个策略获胜。
相关文章:
- 对可变参数使用声明.如何选择正确的功能
- 如果在VC6中使用打开功能,如何选择文件夹?
- c++ Visual Studio 2015 快捷方式,用于从选择代码中生成功能
- 在 Windows 上的C++中使用选择功能进行轮询
- 如何在类中实现可选择的类似命名空间的功能?
- 我的选择排序功能C 有什么问题
- 如何使用std ::有条件地选择一个免费功能
- 明智的选择是更喜欢lambdas功能对象
- QT:无法在ListBoxWidget中的ListBox项目中添加选择和取消选择功能
- 为什么C 编译器选择错误的功能(模板)
- 在不违反干prinicple的情况下,对传递功能对象的参数类型进行模板选择
- 我是否应该使用功能指针在构造函数中选择实现
- 选择何时使用好友功能
- 选择正确功能的更好方法
- 可以编译器告诉我它选择的哪个超载或模板功能
- unix中选择和轮询系统调用之间的功能差异
- C 超载和选择正确的功能
- C++选择功能过早中断
- 如何在斯堪迪尔中参数化选择功能
- 在非阻塞套接字中选择功能