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

标签 c++ templates polymorphism variadic-templates

我有一个多态类型 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/

相关文章:

c++ - 如何将 utf16 ushort 数组转换为 utf8 std::string?

c++ - C++ vector 初始化 list 与分配

java - 模板和泛型。为什么我可以在 C++ 中执行以下操作,但不能在 Java 中执行?我该如何克服这个问题?

c++ - 在模板元编程中使用 "struct xxx<>::val"导致错误

c++ - C++ 函数模板实例化的链接器错误(模板实例化类的成员函数)

c++ - 在成员函数中调用虚函数

scala - 为什么 Scala 在这种特殊情况下无法找到次要隐式值?

Rust 在专用版本中调用函数的默认实现

c++ - 静态断言基指针 "equals"是派生指针

c++ - GDB - 神秘的汇编代码是什么?