Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用基类派生的模板类的正确类型转换从基类访问数据_C++_C++11_Templates - Fatal编程技术网

C++ 使用基类派生的模板类的正确类型转换从基类访问数据

C++ 使用基类派生的模板类的正确类型转换从基类访问数据,c++,c++11,templates,C++,C++11,Templates,我有以下情况: class ScalarField { void* _buffer; //Array for data. }; 和派生类: template <typename T> class ScalarFieldT : public ScalarField { ScalarFieldT(int size) { _data = new T[size]; _buffer = _data; } T& get

我有以下情况:

class ScalarField
{
   void* _buffer; //Array for data.
};
和派生类:

template <typename T> 
class ScalarFieldT : public ScalarField
{
    ScalarFieldT(int size)
    {
       _data = new T[size];
       _buffer = _data;
    }

   T& get(int index)
   {
       return _data[index];
   }

   T* _data; // Typed array for data
};
关键是,我只能访问基类抽象,但我需要从
\u buffer
获取转换为另一种简单数据类型的值,如float、int、uchar等

你们推荐什么


提前谢谢

嗯-请不要为了一个可能愚蠢的回答而对我扔石头,但是

让我们假设
T
仅限于数字数据类型,例如
int
long
double
float
,并进一步假设要存储的最大整数值约为2^53。然后,
double
可以用作数据交换数据类型,任何其他数据类型都可以转换为该数据类型,而不会丢失精度

然后可以定义
virtualdouble-ScalarField::method(int-index)=0
,然后在类型化变量中相应地重载它,这些变量执行从实际类型
T
到双精度的“向上”转换

除非允许您将值封装在对象中(例如结构/类值),否则使用“use double as data exchange数据类型”的以下代码可以工作:

类ScalarField
{
公众:
void*\u buffer;//数据的数组。
虚双法(整数指数)=0;
};
模板
类ScalarFieldT:公共ScalarField
{
公众:
ScalarFieldT(整数大小)
{
_数据=新T[尺寸];
_缓冲区=_数据;
}
虚双精度方法(int-index){return get(index);}
T&get(整数索引)
{
返回数据[索引];
}
T*\u data;//数据的类型化数组
};

您可以使用提供一组强制转换运算符的类型作为
方法的返回类型
下面是一个简单的工作示例:

#include<memory>

class ScalarField {
protected:
    struct Value {
        virtual operator float() const = 0;
        virtual operator int() const = 0;
        // ...
    };

public:
    virtual const Value & method(int i) = 0;

protected:
    void* buffer;
};

template <typename T> 
class ScalarFieldT : public ScalarField {
    struct TValue: Value {
        TValue(T value): value{value} {}
        operator float() const override { return float(value); }
        operator int() const override { return int(value); }
        // ...

    private:
        T value;
    };

public:
    ScalarFieldT(int size) {
        data = new T[size];
        buffer = data;
    }

    T& get(int index) {
        return data[index];
    }

    const Value & method(int i) {
    std::make_unique<TValue>(data[i]);
}

private:
    std::unique_ptr<Value> value;
    T* data;
};

int main() {
    ScalarFieldT<int> typedScalarField(10);
    ScalarField* scalarField = &typedScalarField;
    float f = scalarField->method(2);
    int i = scalarField->method(5);
}
#包括
类ScalarField{
受保护的:
结构值{
虚拟运算符float()常量=0;
虚拟运算符int()常量=0;
// ...
};
公众:
虚拟常量值和方法(int i)=0;
受保护的:
空*缓冲区;
};
模板
类ScalarFieldT:公共ScalarField{
structValue:Value{
TValue(T值):值{value}{}
运算符float()常量重写{return float(value);}
运算符int()常量重写{return int(value);}
// ...
私人:
T值;
};
公众:
ScalarFieldT(整数大小){
数据=新T[尺寸];
缓冲区=数据;
}
T&get(整数索引){
返回数据[索引];
}
常量值和方法(int i){
标准::使_唯一(数据[i]);
}
私人:
std::唯一的ptr值;
T*数据;
};
int main(){
ScalarFieldT类型的Scalarfield(10);
ScalarField*ScalarField=&typedScalarField;
float f=scalarField->method(2);
int i=scalarField->method(5);
}

您希望在该
main()
示例中将
int
转换为
float
,还是希望100%确保
float value=scalarField->get(index)只会被实例化为
ScalarFieldT
的scalarField调用?使用
static\u cast
。因此,基本上,您所拥有的只是一个
void*
指针,而不知道它可能指向什么?那恐怕你用那个指针也没用了。您必须重新审视您的设计。我对您试图解决的问题或您必须努力解决的约束条件了解不够,无法提供建议。@JoãoPauloNavarro是一个可行的解决方案?让我知道,我会把它放在一个答案,如果它适合你。它或多或少地执行您要求的操作,即从底层缓冲区提取参数,将其转换为原始类型,然后转换为请求的类型。
#include<memory>

class ScalarField {
protected:
    struct Value {
        virtual operator float() const = 0;
        virtual operator int() const = 0;
        // ...
    };

public:
    virtual const Value & method(int i) = 0;

protected:
    void* buffer;
};

template <typename T> 
class ScalarFieldT : public ScalarField {
    struct TValue: Value {
        TValue(T value): value{value} {}
        operator float() const override { return float(value); }
        operator int() const override { return int(value); }
        // ...

    private:
        T value;
    };

public:
    ScalarFieldT(int size) {
        data = new T[size];
        buffer = data;
    }

    T& get(int index) {
        return data[index];
    }

    const Value & method(int i) {
    std::make_unique<TValue>(data[i]);
}

private:
    std::unique_ptr<Value> value;
    T* data;
};

int main() {
    ScalarFieldT<int> typedScalarField(10);
    ScalarField* scalarField = &typedScalarField;
    float f = scalarField->method(2);
    int i = scalarField->method(5);
}