gpt4 book ai didi

c++ - 检查指向基类的指针是否是使用可变参数模板派生的指针之一

转载 作者:行者123 更新时间:2023-11-30 03:24:51 24 4
gpt4 key购买 nike

我有一个多态类型 Base,它是许多其他类型的基类:

class Base
{
Base() {}
virtual ~Base() {}
};

其中一个派生类包含一个值,该值由类型 T 模板化。此类还可以包含指向该类的另一个实例 _stub 的指针,它可能是另一种类型 T,以充当值的替换。限制是其他类型必须是可变参数模板指示的受支持类型之一。所以 _stub 是类型 T 或 SupportedTypes 之一。

我希望下面的 getValue 函数做的是,如果 _stub 为 NULL,则返回 T 类型的 _v,否则 dynamic_cast _stub 为其原始派生类型(假设X), 然后把它丢给 T。要求是类型 X 必须有一个转换为 T 的运算符。

_stub 保证是 T 或 SupportedTypes 之一。

template <typename T, typename... SupportedTypes>
class Generic : public Base
{
public:

Generic(): _v() {}
virtual ~Generic() {}

virtual T getValue() {
if (_stub) {
// Attempt dynamic_cast on _stub to type T or
// any of SupportedTypes until we find its original type X

// I'm looking for a solution that would look like the following line
X* p = dynamic_cast<T,SupportedTypes...>(_stub.get());
assert(p);
return (T)*p->_v;
}
return _v;
}

private:
T _v;
std::shared_ptr<Base> _stub;
};

最初,我没有 SupportedTypes 参数包,我会为类型 T 专门化 getValue() 并做一个 dynamic_cast 链,但这取决于每个类型 T,每个类似于 getValue() 的函数都需要这个级联if/else dynamic_cast 汤。

我正在尝试使用可变参数模板 SupportedTypes 进行试验,以便我可以想出一个更好的解决方案,其中派生类只需要指示类型 _stub 可能在一个地方。

有没有人有一个干净的解决方案来解决这个问题?

解决方法:

由于@apple apple 的提示,我实际上选择了 boost::variant

最佳答案

这发生在相关类 Generic 中并且如果指针为 null 则有可能使用另一个值的事实是无关紧要的。你想要的是一个函数模板,它通过 dynamic_cast 转换为从 Base 派生的单个类型,转换为一组类似派生的其他类型之一:

class B;

// The real work:
template<class T>
T convert(B *b) {return static_cast<T&>(*b);}
template<class T,class U,class... Rest>
T convert(B *b) {
if(U *u=dynamic_cast<U*>(b)) return *u; // converted to T
return convert<T,Rest...>(b);
}

// Example hierarchy:
struct B {virtual ~B() {}};
struct X : B {};
struct Y : B {};
struct S : B { // convertible from other types
S() {}
S(X) {}
S(Y) {}
};

// Example usage:
S getS(B *b) {return convert<S,X,Y>(b);}

关于c++ - 检查指向基类的指针是否是使用可变参数模板派生的指针之一,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49462491/

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