gpt4 book ai didi

c++ - 在非虚拟多态类中减少基类到派生委托(delegate)的样板

转载 作者:搜寻专家 更新时间:2023-10-31 02:08:32 24 4
gpt4 key购买 nike

考虑一个封闭的1 类层次结构,如下所示:

class B {...}; 
class D1 final : public B {...};
class D2 final : public B {...};

其中B是一个抽象的2基类,D1D2是它的派生类。

由于实现限制或设计,这些类都没有任何虚拟方法,但 B 上的成员函数在 D1 中有不同的实现和 D2 通过对派生类型进行运行时检查,简单地委托(delegate)给实际的最派生类型,如下所示:

class B {
bool isD1;
protected:
B(bool isD1) : isD1{isD1} {}
public:
std::string to_string() {
return isD1 ? static_cast<D1*>(this)->to_string() : static_cast<D2*>(this)->to_string();
}
}

class D1 final : public B {
public:
D1() : B(true) {}
std::string to_string() { // D1 specific implementation ... }
}

class D2 final : public B {
public:
D2() : B(false) {}
std::string to_string() { // D2 specific implementation ... }
}

B 上的 to_string 方法只是检查 B 的派生程度最高的类型是否为 D1D2 并调用适当的方法(在这两种情况下也称为 to_string)。

很酷。

现在假设还有 10 个方法,如 B::to_string。我可以在 C++11 中做些什么来减少 B 中的委托(delegate)样板,而不求助于宏?

在 C++14 中,通用委托(delegate)机制似乎是一种合理的方法,例如:

class B {
...

template <typename F>
auto delegate(F&& f) -> decltype(f(D1{})) {
return isD1 : f(*static_cast<D1*>(this)) : f(*static_cast<D2*>(this));
}

std::string to_string() {
return delegate([](auto&& b){ return b.to_string(); });
}
}

这里是 [](auto&& b){ return b.to_string(); 无论最终传递的是 D1 还是 D2(因为两者都有 to_string 方法),通用 lambda 都有效。在 C++11 中,我没有看到一种等效的简洁方式来表达这一点。

有什么想法吗?

当然,您可以使用宏来复制一个非泛型宏并将其传递给一个 2 参数 delegate 方法(它为 D1D2) 但我想避免使用宏。


1 这里封闭意味着 B 的派生类集合在运行时是固定的和已知的。

2 抽象在概念上 但不是在“纯粹的虚拟”意义上。也就是说,不应直接实例化此类 - 唯一有意义的完整对象是其派生类。各种构造函数都被保护以强制执行此操作。

最佳答案

这个怎么样?

  template <typename F1, typename F2>
auto delegate(F1 f1, F2 f2) -> decltype((D1{}.*f1)()) {
return isD1 ? (static_cast<D1*>(this)->*f1)() : (static_cast<D2*>(this)->*f2)();
}

std::string to_string() {
return delegate(&D1::to_string, &D2::to_string);
}

你也可以让它变得更强类型:

  template <typename Result>
Result delegate(Result (D1::*f1)(), Result (D2::*f2)()) {
return isD1 ? (static_cast<D1*>(this)->*f1)() : (static_cast<D2*>(this)->*f2)();
}

关于c++ - 在非虚拟多态类中减少基类到派生委托(delegate)的样板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47490452/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com