主要是作爲一個練習我實現從基地B
轉換立足10
:如何減少迭代器的樣板?
unsigned fromBaseB(std::vector<unsigned> x,unsigned b){
unsigned out = 0;
unsigned pow = 1;
for (size_t i=0;i<x.size();i++){
out += pow * x[i];
pow *= b;
}
return out;
}
int main() {
auto z = std::vector<unsigned>(9,0);
z[3] = 1;
std::cout << fromBaseB(z,3) << std::endl;
}
現在我想寫這使用的算法。例如。使用accumulate
我可以寫
unsigned fromBaseB2(std::vector<unsigned> x,unsigned b){
unsigned pow = 1;
return std::accumulate(x.begin(),
x.end(),0u,
[pow,b](unsigned sum,unsigned v) mutable {
unsigned out = pow*v;
pow *= b;
return out+sum;
});
}
但是,我認爲這不是更好的代碼。事實上,將它作爲內部產品寫入會更自然,因爲這正是我們必須計算的基礎變革。但使用inner_product
我需要一個迭代器:
template <typename T> struct pow_iterator{
typedef T value_type;
pow_iterator(T base) : base(base),value(1) {}
T base,value;
pow_iterator& operator++(){ value *= base;return *this; }
T operator*() {return value; }
bool operator==(const pow_iterator& other) const { return value == other.value;}
};
unsigned fromBaseB3(std::vector<unsigned> x,unsigned b){
return std::inner_product(x.begin(),x.end(),pow_iterator<unsigned>(b),0u);
}
使用迭代器,現在稱該算法是不錯的乾淨,但我不得不寫大量的樣板代碼的迭代器。也許這只是我對算法和迭代器應該如何使用的誤解......實際上,這只是我常常遇到的一個普遍問題的一個例子:我有一系列基於簡單模式計算的數字,而我想要有一個迭代器,當解除引用時返回該序列中相應的數字。當序列存儲在一個容器中時,我只需使用容器提供的迭代器,但我也希望這樣做,當沒有容器存儲值時也是如此。我當然可以嘗試編寫自己的通用迭代器來完成這項工作,但是標準庫中是否存在可以幫助您的工作?
對我來說,感覺有點怪怪的,我可以使用lambda欺騙accumulate
成計算內積,而是利用inner_product
直接我必須做些額外的事情(無論是預先計算的權力,並將它們存儲在一個容器中,或者寫一個迭代器,即單獨的class
)。
tl; dr:是否有簡單的方法來減少上述pow_iterator
的樣板?
更一般的問題(但可能太寬泛)問題:對於未存儲在容器中的值序列使用迭代器是否「正常」,但僅在迭代器被解除引用時才計算?有沒有實現它的「C++方法」?
看看boost.iterator庫。特別是iterator_adapter和iterator_facade。 –