编写用于定位C数组,C ++库和C ++标准库的通用代码的最佳方法是什么?
示例:点积
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;
}
访问元素时出现问题:
array[i]
,C矩阵array[i][j]
std::vector
,vector[i]
tuple
,std::get<i>(tuple)
vector(i)
,matrix(i, j)
迭代存在问题:
std::vectors
,... boost::fusion
例如std::array
,std::tuple
,... Boost.Geometry使用get
函数来解决访问问题,从而导致代码完整无处不在get
。它还使用策略来调度不同的迭代方法。
还有更好的选择吗?
答案 0 :(得分:1)
您可以使用基于策略的模板。
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);
}
然后有一些普通类型的默认实现,如果用户有自定义类型,请让用户编写策略。
通用功能将在其所需的策略中记录服务需求。
与std::unique_ptr
和std::default_deleter
类似,可以控制对所拥有指针的破坏。
答案 1 :(得分:1)
您可以将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); }
然后
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;
}