访问序列元素的通用方法 P>编写C数组、C++库和C++标准库?< /P>的通用代码的最佳方法是什么?
示例:点积访问序列元素的通用方法 P>编写C数组、C++库和C++标准库?< /P>的通用代码的最佳方法是什么?,c++,generics,multidimensional-array,C++,Generics,Multidimensional Array,示例:点积 template<class Vector1, class Vector2> constexpr auto dot_product(Vector1 const& v1, Vector2 const& v2) { // doesn't work for Vectors that do not implement () subscripting using return_type = decltype(v1(0) + v2(0)); return
template<class Vector1, class Vector2>
constexpr auto dot_product(Vector1 const& v1, Vector2 const& v2) {
// doesn't work for Vectors that do not implement () subscripting
using return_type = decltype(v1(0) + v2(0));
return_type tmp = return_type{};
// doesn't work for e.g. std::tuple
for (std::size_t i = 0, e = size(v1); i != e; ++i) {
tmp += v1(i) * v2(i);
}
return tmp;
}
模板
constexpr自动点积(矢量1常量和v1,矢量2常量和v2){
//不适用于未实现()下标的向量
使用return_type=decltype(v1(0)+v2(0));
return_type tmp=return_type{};
//不适用于例如std::tuple
对于(std::size\u t i=0,e=size(v1);i!=e;++i){
tmp+=v1(i)*v2(i);
}
返回tmp;
}
- 访问元素时出现问题:
- 对于C数组
,C矩阵数组[i]
数组[i][j]
- C++ >代码> STD::向量< /代码>,代码>矢量[i] < /Calp> <> LI>对于C++ +>代码>元组,<代码> STD::GET(元组)< /C> < /LI> 对于一个C++线性代数向量/矩阵(如本征):<代码>向量(I)< /COD>,<代码>矩阵(I,J)< /COD>
- 对于C数组
- C数组循环的运行时,
std::vectors
用于例如boost::fusion
,std::array
std::tuple
- 线性代数库的自定义表达式,可在封面下处理这两种情况(例如,Eigen使用表达式模板)
get
函数来解决访问问题,这会导致到处都是get
s的卷积代码。它还使用策略来调度不同的迭代方法有更好的替代方案吗?您可以使用基于策略的模板
template <typename T>
struct DefaultUsePolicy {
int DoSomethingWithT( T const & ) {
return 42;
}
};
template < typename T, typename UsePolicy = DefaultUsePolicy<T>>
int Generic( T& arg ) {
UsePolicy use;
return use.DoSomethingWithT(arg);
}
模板
结构DefaultUsePolicy{
int dosomethingWith(T const&){
返回42;
}
};
模板
int通用(T&arg){
使用政策使用;
返回use.DoSomethingWithT(arg);
}
然后为公共类型提供一些默认实现,如果用户有自定义类型,则让用户编写一个策略
通用功能将在其所需的策略中记录服务需求
它类似于使用
std::unique\u ptr
和std::default\u deleter
来提供对销毁所拥有指针的控制。您可以将get
函数包装在类中,类似于:
#define Return(ret) decltype ret { return ret; }
template <typename T>
class Getter
{
private:
T& t;
public:
constexpr explicit Getter(T&t) : t(t) {}
constexpr auto operator () (std::size_t i) const
-> Return((get(t, i)))
constexpr auto operator () (std::size_t i, std::size_t j) const
-> Return((get(t, i, j)))
operator T&() const { return t; }
};
template <typename T>
Getter<T> make_getter(T&t) { return Getter<T>(t); }
#定义返回(ret)decltype ret{Return ret;}
模板
类吸气剂
{
私人:
T&T;
公众:
constexpr显式Getter(T&T):T(T){
constexpr自动运算符()(std::size\u t i)const
->返回((get(t,i)))
constexpr自动运算符()(std::size\u t i,std::size\u t j)const
->返回((get(t,i,j)))
运算符T&()常量{return T;}
};
模板
Getter make_Getter(T&T){return Getter(T);}
然后
template<class Vector1, class Vector2>
constexpr auto dot_product(Vector1 const& v1_arg, Vector2 const& v2_arg) {
auto v1 = make_getter(v1_arg);
auto v2 = make_getter(v2_arg);
using return_type = decltype(v1(0) + v2(0));
return_type tmp = return_type{};
for (std::size_t i = 0, e = size(v1); i != e; ++i) {
tmp += v1(i) * v2(i);
}
return tmp;
}
模板
constexpr自动点积(矢量1常量和v1常量、矢量2常量和v2常量){
auto v1=制造吸气剂(v1_arg);
自动v2=生成getter(v2\u arg);
使用return_type=decltype(v1(0)+v2(0));
return_type tmp=return_type{};
对于(std::size\u t i=0,e=size(v1);i!=e;++i){
tmp+=v1(i)*v2(i);
}
返回tmp;
}
Generic access您是在谈论索引operator[]()
重载吗?@πάνταῥεῖ 不一定,但大部分是肯定的。你所说的(即[i,j]是允许的,但[i][j]不是)是什么意思。这是不正确的。@对于用户定义的类型很简单。我强调了这一点,并在数组访问之前添加了运算符,以使其更加清晰。@gnzlbg您不能使[I,j]
对用户定义的类型有效。这是逗号运算符。