我正在构建 xtensor 示例 “嵌入形状和步幅的结构”,将其用于具有自己的标头信息的图像类。我已经做到了这一点:
#include <xtensor/xadapt.hpp>
#include <xtensor/xstrides.hpp>
// see https://github.com/xtensor-stack/xtensor/blob/master/docs/source/external-structures.rst
template <class T>
struct raw_tensor {
using container_type = std::vector<T>;
using shape_type = std::vector<std::size_t>;
container_type
m_data;
shape_type
m_shape,
m_strides,
m_backstrides;
static constexpr xt::layout_type
layout = xt::layout_type::dynamic;
};
template <class T>
class raw_tensor_adaptor;
template <class T>
struct xt::xcontainer_inner_types<raw_tensor_adaptor<T>> {
using container_type = typename raw_tensor<T>::container_type;
using inner_shape_type = typename raw_tensor<T>::shape_type;
using inner_strides_type = inner_shape_type;
using inner_backstrides_type = inner_shape_type;
using shape_type = inner_shape_type;
using strides_type = inner_shape_type;
using backstrides_type = inner_shape_type;
static constexpr layout_type layout = raw_tensor<T>::layout;
};
template <class T>
struct xt::xiterable_inner_types<raw_tensor_adaptor<T>>
: xcontainer_iterable_types<raw_tensor_adaptor<T>> {
};
template <class T>
class raw_tensor_adaptor : public xt::xcontainer<raw_tensor_adaptor<T>>,
public xt::xcontainer_semantic<raw_tensor_adaptor<T>> {
public:
using self_type = raw_tensor_adaptor<T>;
using base_type = xt::xcontainer<self_type>;
using semantic_base = xt::xcontainer_semantic<self_type>;
raw_tensor_adaptor(const raw_tensor_adaptor&) = default;
raw_tensor_adaptor& operator=(const raw_tensor_adaptor&) = default;
raw_tensor_adaptor(raw_tensor_adaptor&&) = default;
raw_tensor_adaptor& operator=(raw_tensor_adaptor&&) = default;
template <class E>
raw_tensor_adaptor(const xt::xexpression<E>& e) : base_type() {
semantic_base::assign(e);
}
template <class E>
self_type& operator=(const xt::xexpression<E>& e) {
return semantic_base::operator=(e);
}
};
int main() {
raw_tensor<double> i,j,k; // this works
using tensor_type = raw_tensor_adaptor<double>;
// tensor_type a, b, c; // but not this if un-commented
// .... init a, b, c
// tensor_type d = a + b - c; raw_tensor < int > a;
return 0;
}
使用仅声明类
main()
对象的 raw_tensor<double>
函数,编译可以顺利完成。
在 Linux(使用 gcc-11)上,我可以通过执行以下操作(重新)运行此示例:
$ cd /tmp && mkdir -p xtensor-test && cd xtensor-test
$ git clone https://github.com/xtensor-stack/xtensor.git
$ git clone https://github.com/xtensor-stack/xtl.git
$ vi xtensor-test.cpp # insert the code block above and save
$ g++ -o xtensor-test xtensor-test.cpp -Ixtensor/include -Ixtl/include
但是,我不能做这些事情:
resize()
或 accessor 方法:当我在类中添加 resize()
函数(没有模板参数 T
)时,这不起作用,因为内部类型和成员 shape_type
、m_shape
等未知。但这是唯一超载的地方resize()
,对吗?using tensor_type = raw_tensor_adaptor<double>;
tensor_type a, b, c;
当我声明这些适配器时,
a, b, c
行会生成以下错误:
include/xtensor/xiterable.hpp:288:19: error: no type named 'xexpression_type' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >’
include/xtensor/xaccessible.hpp:35:15: error: no type named 'reference' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >’
include/xtensor/xaccessible.hpp:36:15: error: no type named 'const_reference' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >’
include/xtensor/xaccessible.hpp:37:15: error: no type named 'size_type' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >’
include/xtensor/xaccessible.hpp:47:48: error: no type named 'const_reference' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >’
include/xtensor/xaccessible.hpp:111:26: error: 'at' has not been declared in 'using base_type = class
include/xtensor/xaccessible.hpp:112:35: error: 'operator[]' has not been declared in 'using base_type = class xt::xconst_accessible<raw_tensor_adaptor<double> >’ {aka ‘class xt::xconst_accessible<raw_tensor_adaptor<double> >’}
include/xtensor/xaccessible.hpp:113:26: error: 'back' has not been declared in 'using base_type = class xt::xconst_accessible<raw_tensor_adaptor<double> >’ {aka ‘class xt::xconst_accessible<raw_tensor_adaptor<double> >’}
include/xtensor/xaccessible.hpp:114:26: error: 'front' has not been declared in 'using base_type = class xt::xconst_accessible<raw_tensor_adaptor<double> >’ {aka ‘class xt::xconst_accessible<raw_tensor_adaptor<double> >’}
include/xtensor/xaccessible.hpp:115:26: error: 'periodic' has not been declared in 'using base_type = class xt::xconst_accessible<raw_tensor_adaptor<double> >’ {aka ‘class xt::xconst_accessible<raw_tensor_adaptor<double> >’}
include/xtensor/xcontainer.hpp:79:15: error: no type named 'storage_type' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >'
include/xtensor/xcontainer.hpp:80:15: error: no type named 'storage_type' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >'
include/xtensor/xcontainer.hpp:82:15: error: no type named 'reference' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >'
include/xtensor/xcontainer.hpp:83:15: error: no type named 'const_reference' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >'
include/xtensor/xcontainer.hpp:86:15: error: no type named 'size_type' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >'
include/xtensor/xcontainer.hpp:88:15: error: no type named 'storage_type' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >'
include/xtensor/xcontainer.hpp:89:15: error: no type named 'storage_type' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >'
include/xtensor/xcontainer.hpp:107:15: error: no type named 'storage_type' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >'
include/xtensor/xcontainer.hpp:108:15: error: no type named 'storage_type' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >'
include/xtensor/xcontainer.hpp:140:32: error: 'at' has not been declared in 'using accessible_base = class xt::xaccessible<raw_tensor_adaptor<double> >’ {aka ‘class xt::xaccessible<raw_tensor_adaptor<double> >’}
include/xtensor/xcontainer.hpp:141:32: error: 'shape' has not been declared in 'using accessible_base = class xt::xaccessible<raw_tensor_adaptor<double> >’ {aka ‘class xt::xaccessible<raw_tensor_adaptor<double> >’}
include/xtensor/xcontainer.hpp:142:41: error: 'operator[]' has not been declared in 'using accessible_base = class xt::xaccessible<raw_tensor_adaptor<double> >’ {aka ‘class xt::xaccessible<raw_tensor_adaptor<double> >’}
include/xtensor/xcontainer.hpp:143:32: error: 'back' has not been declared in 'using accessible_base = class xt::xaccessible<raw_tensor_adaptor<double> >’ {aka ‘class xt::xaccessible<raw_tensor_adaptor<double> >’}
include/xtensor/xcontainer.hpp:144:32: error: 'front' has not been declared in 'using accessible_base = class xt::xaccessible<raw_tensor_adaptor<double> >’ {aka ‘class xt::xaccessible<raw_tensor_adaptor<double> >’}
include/xtensor/xcontainer.hpp:146:32: error: 'periodic' has not been declared in 'using accessible_base = class xt::xaccessible<raw_tensor_adaptor<double> >’ {aka ‘class xt::xaccessible<raw_tensor_adaptor<double> >’}
include/xtensor/xcontainer.hpp:182:15: error: no type named 'storage_type' in 'struct
include/xtensor/xsemantic.hpp:64:15: error: no type named 'temporary_type' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >’
来自
xtensor
标题和
xtensor-test.cpp:70:13: error: no matching function for call to ‘raw_tensor_adaptor<double>::raw_tensor_adaptor()’
tensor_type a, b, c; // but not this if un-commented
^
xtensor-test.cpp:55:5: note: candidate: ‘template<class E> raw_tensor_adaptor<T>::raw_tensor_adaptor(const xt::xexpression<E>&)’
raw_tensor_adaptor(const xt::xexpression<E>& e) : base_type() {
^~~~~~~~~~~~~~~~~~
xtensor-test.cpp:55:5: note: template argument deduction/substitution failed:
xtensor-test.cpp:70:13: note: candidate expects 1 argument, 0 provided
tensor_type a, b, c; // but not this if un-commented
^
xtensor-test.cpp:51:5: note: candidate: ‘raw_tensor_adaptor<T>::raw_tensor_adaptor(raw_tensor_adaptor<T>&&) [with T = double]’
raw_tensor_adaptor(raw_tensor_adaptor&&) = default;
^~~~~~~~~~~~~~~~~~
xtensor-test.cpp:51:5: note: candidate expects 1 argument, 0 provided
xtensor-test.cpp:49:5: note: candidate: ‘raw_tensor_adaptor<T>::raw_tensor_adaptor(const raw_tensor_adaptor<T>&) [with T = double]’
raw_tensor_adaptor(const raw_tensor_adaptor&) = default;
^~~~~~~~~~~~~~~~~~
xtensor-test.cpp:49:5: note: candidate expects 1 argument, 0 provided
xtensor-test.cpp:49:5: note: candidate: ‘raw_tensor_adaptor<T>::raw_tensor_adaptor(const raw_tensor_adaptor<T>&) [with T = double]’
raw_tensor_adaptor(const raw_tensor_adaptor&) = default;
^~~~~~~~~~~~~~~~~~
来自
.cpp
文件
网页表示定义语义并实现特定于 raw_tensor 结构的方法和函数。但我感觉我做错了地方。
有人让这个示例与 raw_tensor_adaptor 实例一起使用吗? 非常感谢!
1。定义内部类型
您需要正确定义 xtensor 所需的内部类型和方法,以确保您的适配器类与 xtensor 库顺利工作。类型应该与 xtensor 期望的类型一致。您已经部分定义了 xcontainer_inner_types 和 xiterable_inner_types,但缺少一些关键类型和方法。
这是 raw_tensor_adaptor 类的精炼版本,具有完整的定义:
#include <vector>
#include <xtensor/xadapt.hpp>
#include <xtensor/xstrides.hpp>
template <class T>
struct raw_tensor {
using container_type = std::vector<T>;
using shape_type = std::vector<std::size_t>;
container_type m_data;
shape_type m_shape;
shape_type m_strides;
shape_type m_backstrides;
static constexpr xt::layout_type layout = xt::layout_type::dynamic;
};
template <class T>
class raw_tensor_adaptor;
template <class T>
struct xt::xcontainer_inner_types<raw_tensor_adaptor<T>> {
using container_type = typename raw_tensor<T>::container_type;
using inner_shape_type = typename raw_tensor<T>::shape_type;
using shape_type = inner_shape_type;
using strides_type = inner_shape_type;
using backstrides_type = inner_shape_type;
using storage_type = container_type;
using reference = T&;
using const_reference = const T&;
using size_type = typename container_type::size_type;
using difference_type = typename container_type::difference_type;
static constexpr layout_type layout = raw_tensor<T>::layout;
};
template <class T>
struct xt::xiterable_inner_types<raw_tensor_adaptor<T>>
: xt::xcontainer_iterable_types<raw_tensor_adaptor<T>> {
};
template <class T>
class raw_tensor_adaptor : public xt::xcontainer<raw_tensor_adaptor<T>>,
public xt::xcontainer_semantic<raw_tensor_adaptor<T>> {
public:
using self_type = raw_tensor_adaptor<T>;
using base_type = xt::xcontainer<self_type>;
using semantic_base = xt::xcontainer_semantic<self_type>;
raw_tensor_adaptor() = default;
raw_tensor_adaptor(const raw_tensor_adaptor&) = default;
raw_tensor_adaptor& operator=(const raw_tensor_adaptor&) = default;
raw_tensor_adaptor(raw_tensor_adaptor&&) = default;
raw_tensor_adaptor& operator=(raw_tensor_adaptor&&) = default;
template <class E>
raw_tensor_adaptor(const xt::xexpression<E>& e) : base_type() {
semantic_base::assign(e);
}
template <class E>
self_type& operator=(const xt::xexpression<E>& e) {
return semantic_base::operator=(e);
}
// Implement the resize method
void resize(const typename raw_tensor<T>::shape_type& new_shape) {
// Update shape and possibly resize data if needed
m_shape = new_shape;
// TODO: Implement resizing logic for m_data based on new_shape and strides
}
// Accessor methods
auto shape() const {
return m_shape;
}
auto& data() {
return m_data;
}
private:
raw_tensor<T> m_raw_tensor;
};
2。实现方法和函数
在精炼后的 raw_tensor_adaptor 类中,我添加了默认构造函数并实现了调整大小方法。您需要确保 resize 方法和其他访问器方法在 m_shape、m_data 和其他成员上正确运行。
3.确保正确的类型定义
确保在 raw_tensor_adaptor 的 xcontainer_inner_types 中正确定义了引用、const_reference、size_type 和 storage_type 等类型。
4。编译
通过这些更改,您应该能够编译程序而不会出现遇到的错误。确保 xtensor 和 xtl 库已正确包含并且是最新的。
用法示例
完成这些更改后,您应该能够声明 raw_tensor_adaptor 对象并执行加法等操作:
int main() {
raw_tensor<double> raw1, raw2, raw3;
using tensor_type = raw_tensor_adaptor<double>;
tensor_type a, b, c;
// Initialize a, b, and c as needed
// tensor_type d = a + b - c; // Ensure that operator+ and operator- are correctly implemented
return 0;
}
如果您打算使用必要的算术运算(operator+、operator-等),请确保实现它们,因为 xtensor 不会自动提供这些运算。
通过执行这些步骤,您应该能够为自定义张量结构创建一个可用的 xtensor 适配器。