如何围绕表达式模板编写第三方库包装类
How to write a third-party library wrapper class around expression templates
我们正试图在我的研究小组中实现一个新的C++代码来执行大型数值模拟(有限元、有限差分方法、拓扑优化等)该软件将被学术界和工业界人士使用。
对于软件的密集线性代数部分,我们希望使用特征或犰狳。我们希望围绕这些包构建一个包装器,原因有两个:1. 向用户公开我们自己的 API,而不是第三方 API;和 2.以防我们将来需要切换库。我知道原因 2 是一种非常昂贵的保险形式,但我们在以前的模拟软件中遇到了这种情况。
我遇到的有关包装第三方库的信息来自以下来源:
-
是否应该在我的C++库的 API 中公开第三方类型
-
https://softwareengineering.stackexchange.com/questions/107338/using-third-party-libraries-always-use-a-wrapper
我的问题与构建此包装器类的最佳方法有关。 理想情况下,薄层包装器是最好的,因为:
template< typename T >
class my_vec {
private:
arma::Col< T > _arma_vec;
};
或等效于特征向量。
然后,我的类会将第三方库类调用为:
my_vec::foo() { return _arma_vec.foo(); }
我认为(我想确认这一点)这个薄层的问题在于我失去了从这些库在后台实现的表达式模板中获得的速度。例如,在犰狳中,以下操作:
// Assuming these vectors were already populated.
a = b + c + d;
变成这样:
for ( std::size_t i = 0; i < a.size(); ++i ) {
a[i] = b[i] + c[i] + d[i];
}
由于表达式模板的实现,无需创建任何临时。同样的情况也适用于本征。
据我所知,我失去表达式模板功能的原因是,虽然犰狳或本征不会创建自己的临时,但我的类my_vec可以。避免这种情况的唯一方法是在其表达式模板周围构建一个薄层包装器。然而,在这一点上,这似乎违反了YAGNI原则。
这个相关的问题在这里:
- 如何集成使用表达式模板的库?
建议使用类似以下内容:
my_vec a, b, c;
// ... populate vectors
a._arma_vec = b._arma_vec + c._arma_vec;
是否可以改用这样的东西?
template< typename T >
arma::Col< T > &
my_vec< T >::data() { return _arma_vec; }
a.data() = b.data() + c.data();
或者使用一些运算符重载来向用户隐藏 data()?如果我们不想直接使用这些库,还有什么其他选择?使用宏?如果我们决定使用 C++11,请使用别名?
或者构建这个包装类最方便的方法是什么?
仅供将来参考,这就是我决定实现解决方案的方式: 我通过以下方式重载了运算符+:
template< typename T1, typename T2 >
auto
operator+(
const my_vec< T1 > & X,
const my_vec< T2 > & Y ) ->decltype( X.data() + Y.data() )
{
return X.data() + Y.data();
}
template< typename T1, typename T2 >
auto
operator+(
const my_vec< T1 > & X,
const T2 & Y ) ->decltype( X.data() + Y )
{
return X.data() + Y;
}
template< typename T1, typename T2 >
auto
operator+(
const T1 & X,
const my_vec< T2 > & Y ) ->decltype( X + Y.data() )
{
return X + Y.data();
}
然后,我在类中重载了我的运算符 = my_vec以下内容:
template< typename T >
template< typename A >
const my_vec< T > &
my_vec< T >::operator=(
const A & X )
{
_arma_vec = X;
return *this;
}
- 简化在 Pybind11 中为 C++ 模板类生成包装类:模板声明不能出现在块范围内
- C++-用与被包装数据相同的语法构造包装类
- C++-用和结构相同的语法围绕结构构造包装类
- C++泛型包装类,它为某些函数添加了额外的处理
- 如何减少大量包装类的实现代码?
- 在 C++ 中为 C 样式对象创建一个透明包装类
- 如何将包装类的对象用作包装函数中的参数
- 这->...在模板包装类中必需
- 无法理解包装类的构造函数的声明
- 标准向量之上的 C++11 包装类
- 编写安全包装类以管理用户定义对象的指针
- 重构现有包装类,以使用与包装器本身相同的构造函数参数包装 T
- 包装类设计和依赖注入
- 提升 Python 导入失败,未定义包装类的符号
- 简单包装类与智能指针
- 将 C 结构工厂函数与其相应的 C++ 包装类构造函数合并
- 为什么这个C++包装类没有内联掉
- std::variant、包装类和'conversion from ... to non-scalar type ... requested'
- C# 使用包装类中的字符串参数调用 C++ 方法
- 如何围绕表达式模板编写第三方库包装类