我想要寫一個binary indexed array
一類,C++的std ::加爲模板參數
它使用兩個非類型的默認模板參數,op
和identity
。
而需要檢查的約束條件是op(identity,identity) == identity
。
我的問題是,
- 我也不怎麼指定
op
,我目前的解決方案不會編譯。‘class std::function<T(T, T)>’ is not a valid type for a template non-type parameter
- 如何檢查
op(identity,identity) == identity
,目前我無法證實,因爲失敗的第一步,也許static_assert
?
因此,目前我使用下面的解決方法,但我不能指定op
,例如,std::multiplies<int>
。 誰能告訴我如何實現目標?
#include <vector>
#include <functional>
// template <typename T = int, std::function<T(T,T)> op = std::plus<T>(), const T identity = T()>
template <typename T = int, const T identity = T()> // currently workaround
class BIT { // binary indexed array
const std::function<T(T,T)> op = std::plus<T>(); // currently workaround
public:
BIT(std::vector<T> value) : value(value), prefixSum(value.size() + 1, identity) {
for (size_t i = 1; i < prefixSum.size(); ++i) {
incrementNodeByValue(i, value[i-1]);
}
// print(prefixSum,"prefixSum");
}
T getSum(size_t i) {
auto sum = identity;
while (i) {
sum = op(sum, prefixSum(i));
i = firstSmallerAncestor(i);
}
return sum;
}
void incrementNodeByValue(size_t i, T x) {
while (i < prefixSum.size()) {
prefixSum[i] = op(prefixSum[i], x);
i = firstLargerAncestor(i);
}
}
private:
inline size_t firstLargerAncestor(size_t node) { return node + (node & -node); }
inline size_t firstSmallerAncestor(size_t node) { return node & (node - 1); }
std::vector<T> value;
std::vector<T> prefixSum;
};
int main() {
auto vec = std::vector<int> {5,1,15,11,52,28,0};
auto bit = BIT<>(vec);
}
P.S.上面的代碼編譯和工作得很好,第一行註釋掉了我的失敗嘗試,'class BIT'之上和之下的兩行是解決方法。 – qeatzy
如果您的問題已解決,請接受答案。 – apmccartney