【问题标题】:Can I access different template class object via a same pointer?我可以通过同一个指针访问不同的模板类对象吗?
【发布时间】:2020-10-09 09:44:01
【问题描述】:

我正在尝试通过getData() 成员函数访问NDArray 类的data_ 成员。

typedef void * datahandle_t;

enum class typeFlag {
kFloat32 = 0,
kFloat64 = 1,
kUint8 = 2
};

class NDArray{

    private:
        typeFlag dtype_;
        size_t size_;
        datahandle_t data_;

    public:
        // constructor
        NDArray(); 
        NDArray(const size_t size, typeFlag dtype);
        
        // alloc TBlob object
        void alloc();

        const auto getData() const {if (data_) return data_->dptr_;}
        // ...
}

inline NDArray::NDArray(): dtype_(typeFlag::kFloat32), size_(size),  data_(nullptr) {}
inline NDArray::NDArray(const size_t size, typeFlag dtype):  dtype_(dtype), size_(size) {alloc();}

inline void NDArray::alloc(){
        switch(dtype_){
            case typeFlag::kFloat32:
                data_ = std::make_shared<TBlob<float> >(size_);
                break;
            case typeFlag::kFloat64:
                data_ = std::make_shared<TBlob<double> >(size_);
                break;
            // ...
        }

template<typename dtype>
class TBlob{
    friend class NDArray;

    public:
        TBlob();
        explicit TBlob(const size_t size);
        ~TBlob();

    private:
        size_t size_;
        void *dptr_;
};

template<typename dtype>
inline TBlob<dtype>::TBlob(const size_t size): size_(size), dptr_(new dtype[size]) {}

测试代码:

#include <iostream>

NDArray n(18, typeFlag::kFloat32);
for(int i=0; i<18; i++)  std::cout << int(n.getData()[i]) << " ";

首先我通过在构造函数中调用alloc() 来构造一个NDArray 对象。它会将不同的TBlob 对象分配给void * data_ 成员;

然后我希望我可以访问我制作的TBlob 对象,但我得到了错误:

testTBlob.cc:52:60: warning: pointer of type ‘void *’ used in arithmetic [-Wpointer-arith]
     for(int i=0; i<18; i++)  std::cout << int(n.getData()[i]) << " ";
                                                            ^
testTBlob.cc:52:60: error: ‘void*’ is not a pointer-to-object type

看来我还有一个void * 对象。

我想创建一个泛型类NDArray,而TBlob 是一个模板类,根据成员dtype_ 包含不同类型(float、int 等)。我想通过 data_ 成员访问 TBlob 对象,所以我希望它不是 void*,而是指向 TBlob 对象的智能指针。

如何访问已在内存中构造的特定对象(例如,TBlob&lt;float&gt; 对象)?

【问题讨论】:

  • 你必须reinterpret_cast你的void*指针指向一个特定的指针类型。但是在你的代码中有很多奇怪的行。例如。您将std::shared_ptr 分配给void*,这甚至不应该编译。您尝试在您的数据上使用opertator[],即使您的TBlob 类没有重载此运算符。您的示例包含许多不相关的代码,例如上下文、形状等。请改为发布 mcve
  • 顺便说一句,你为什么希望它不是一个 void*?
  • @pptaszni 我现在已经编辑好了,operator[] 是在内置数组上执行的。
  • @user253751 我想创建一个泛型类NDArray,而TBlob 是一个模板类,根据成员dtype_ 包含不同类型(float、int 等)。我想通过data_ 成员访问TBlob 对象,所以我希望它不是void*,而是指向TBlob 对象的智能指针。
  • 嗯,getData 必须有一个返回类型,如果返回类型是 TBlob 那么它就不能也是 TBlob。除非您将 getData 设为模板。你也可以让它返回 void* 并让调用者做演员。

标签: c++ templates


【解决方案1】:

你可以直接使用std::variant,在C++17之后。

如果您不能使用它或只想定义另一个,请参考tagged union

【讨论】:

  • 这就是我想要的!谢谢!
  • 请注意,您仍然需要知道变体中的类型,以便使用它...
  • @user253751 显然是std::variant&lt;std::vector&lt;float&gt;, std::vector&lt;double&gt;, ...&gt;,不是吗?
  • @RedFog 我的意思是当你想访问变体中的向量时,你需要知道它是什么类型,或者使用模板来生成所有的情况。
  • @user253751 你可以(std::get),但你不需要(std::visit)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-18
  • 2020-01-18
  • 2018-08-19
  • 1970-01-01
相关资源
最近更新 更多