C++ 如何设计getData()的返回类型? #包括 #包括 typedef无符号字符uint8; 枚举类类型标志{ kFloat32=0, kFloat64=1, kUint8=2 }; 等级:Ndaray; 模板 类TBlob{ 朋友班; 公众: TBlob():dptr_(nullptr){}; TBlob(size_t size):dptr(new t[size]){}; ~TBlob(){if(dptr_)delete[]dptr_;} 私人: T*dptr; }; 使用datahandle=std::variant; 班轮{ 公众: NDArray():dtype_(typeFlag::kFloat32){ NDArray(size_t size,typeFlag dtype):dtype_(dtype){alloc(size);} ~NDArray(){if(&data)}删除&data;} 空隙分配(尺寸){ 开关(数据类型){ 案例类型标志::kFloat32: 数据=新的TBlob(大小); 打破 案例类型标志::kFloat64: 数据=新的TBlob(大小); 打破 案例类型标志::kUint8: 数据=新的TBlob(大小); 打破 违约: 数据=新的TBlob(大小); 打破 } } 常量自动获取数据(){ if(dtype \==typeFlag::kFloat32)返回std::get(data \)->dptr; else if(dtype \==typeFlag::kFloat64)返回std::get(data \)->dptr; 否则返回std::get(data)->dptr; } 私人: typeFlag-dtype; 数据处理数据; }; int main(){ NDArray a(5,typeFlag::kUint8); std::cout dptr_u; ^~~~~
似乎C++ 如何设计getData()的返回类型? #包括 #包括 typedef无符号字符uint8; 枚举类类型标志{ kFloat32=0, kFloat64=1, kUint8=2 }; 等级:Ndaray; 模板 类TBlob{ 朋友班; 公众: TBlob():dptr_(nullptr){}; TBlob(size_t size):dptr(new t[size]){}; ~TBlob(){if(dptr_)delete[]dptr_;} 私人: T*dptr; }; 使用datahandle=std::variant; 班轮{ 公众: NDArray():dtype_(typeFlag::kFloat32){ NDArray(size_t size,typeFlag dtype):dtype_(dtype){alloc(size);} ~NDArray(){if(&data)}删除&data;} 空隙分配(尺寸){ 开关(数据类型){ 案例类型标志::kFloat32: 数据=新的TBlob(大小); 打破 案例类型标志::kFloat64: 数据=新的TBlob(大小); 打破 案例类型标志::kUint8: 数据=新的TBlob(大小); 打破 违约: 数据=新的TBlob(大小); 打破 } } 常量自动获取数据(){ if(dtype \==typeFlag::kFloat32)返回std::get(data \)->dptr; else if(dtype \==typeFlag::kFloat64)返回std::get(data \)->dptr; 否则返回std::get(data)->dptr; } 私人: typeFlag-dtype; 数据处理数据; }; int main(){ NDArray a(5,typeFlag::kUint8); std::cout dptr_u; ^~~~~,c++,templates,C++,Templates,似乎getData()函数总是根据dtype\uu的默认值返回一个float*类型,即float 如何根据dtype\uuuu的运行时值返回不同的类型?我需要处理getData()返回的指针,这些操作与此指针的类型无关。例如: NDArray NDArray::运算符*(常量浮点标量)常量{ NDArray ret(*本); 对于(尺寸i=0;i 单个非模板函数(或类成员)的返回类型不能依赖于某个运行时值(dtype),这是错误的核心。编译器尝试推断单个返回类型,但失败了,因为不同的代码路径返回
getData()
函数总是根据dtype\uu
的默认值返回一个float*
类型,即float
如何根据dtype\uuuu
的运行时值返回不同的类型?我需要处理getData()
返回的指针,这些操作与此指针的类型无关。例如:
NDArray NDArray::运算符*(常量浮点标量)常量{
NDArray ret(*本);
对于(尺寸i=0;i
单个非模板函数(或类成员)的返回类型不能依赖于某个运行时值(dtype
),这是错误的核心。编译器尝试推断单个返回类型,但失败了,因为不同的代码路径返回float*
、double*
和uint8.
您的操作并不依赖于指针的类型。在这一行中,ret.getData()[i]*=scalar
您已经需要知道类型,以便正确索引(部分)和正确乘法(部分)
您可以在这里做很多选择。我建议将NDArray
制作成一个模板本身,它可以保存一个数据指针和一个大小,而不带任何类型标志。这将使事情变得更加简单和经得起未来考验(例如,如果您决定还需要存储uint16\u t
,则不会有任何中断)
但是,如果您绝对必须使用此3类型布局,并对该类型进行运行时推断,则可以大致执行以下操作。添加一个apply
函数,该函数将接受任何可调用对象,并使用适当的数据类型调用它,例如
class NDArray {
...
template <typename F>
void apply(F f) {
if (dtype_ == typeFlag::kFloat32)
f(std::get<0>(data_)->dptr_, getSize());
else if (dtype_ == typeFlag::kFloat64)
f(std::get<1>(data_)->dptr_, getSize());
else
f(std::get<2>(data_)->dptr_, getSize());
}
...
};
注意,为了简单起见,这个apply
复制了callable,但是它应该接受转发引用并进行适当的转发,如
template <typename F>
void apply(F && f) {
...
std::forward<F>(f)(std::get<0>(data_)->dptr_, getSize());
...
}
模板
无效应用(F&F){
...
std::forward(f)(std::get(data)->dptr,getSize());
...
}
单个非模板函数(或类成员)的返回类型不能依赖于某个运行时值(dtype
),这是错误的核心。编译器尝试推断单个返回类型,但失败了,因为不同的代码路径返回float*
、double*
和uint8.
您的操作并不依赖于指针的类型。在这一行中,ret.getData()[i]*=scalar
您已经需要知道类型,以便正确索引(部分)和正确乘法(部分)
您可以在这里做很多选择。我建议将NDArray
制作成一个模板本身,它可以保存一个数据指针和一个大小,而不带任何类型标志。这将使事情变得更加简单和经得起未来考验(例如,如果您决定还需要存储uint16\u t
,则不会有任何中断)
但是,如果您绝对必须使用此3类型布局,并对该类型进行运行时推断,则可以大致执行以下操作。添加一个apply
函数,该函数将接受任何可调用对象,并使用适当的数据类型调用它,例如
class NDArray {
...
template <typename F>
void apply(F f) {
if (dtype_ == typeFlag::kFloat32)
f(std::get<0>(data_)->dptr_, getSize());
else if (dtype_ == typeFlag::kFloat64)
f(std::get<1>(data_)->dptr_, getSize());
else
f(std::get<2>(data_)->dptr_, getSize());
}
...
};
注意,为了简单起见,这个apply
复制了callable,但是它应该接受转发引用并进行适当的转发,如
template <typename F>
void apply(F && f) {
...
std::forward<F>(f)(std::get<0>(data_)->dptr_, getSize());
...
}
模板
无效应用(F&F){
...
std::forward(f)(std::get(data)->dptr,getSize());
...
}
我将模板数据
并删除数据类型
:
template <typename TData>
class NDArray
{
public:
...
const TData getData() { return std::get<0>(data_)->dptr_; }
private:
TData data_;
}
我将模板数据
并删除数据类型
:
template <typename TData>
class NDArray
{
public:
...
const TData getData() { return std::get<0>(data_)->dptr_; }
private:
TData data_;
}
无法从单个函数执行此操作,因为返回类型不是函数签名的一部分。例如,int foo();
和double foo();
是同一个函数,因此不能同时存在
由于您的代码已在内部使用变体,因此您可以将访问函数设计为类似于std::variant
。例如,将访问器作为模板:
template <typeFlag Type>
auto const & getData () {
if constexpr (Type == typeFlag::kFloat32) { return std::get<0>(data_)->dptr_; }
else if constexpr (Type == typeFlag::kFloat64) { return std::get<1>(data_)->dptr_; }
else { return std::get<2>(data_)->dptr_; }
}
模板
自动常量和获取数据(){
如果constexpr(Type==typeFlag::kFloat32){返回std::get(data)->dptr}
如果constexpr(Type==typeFlag::kFloat64){return std::get(data)->dptr}
else{return std::get(data)->dptr}
}
当然,这需要调用方知道哪个模板