【发布时间】:2019-10-18 10:23:27
【问题描述】:
我想创建一个集合包装器,其中 end 方法将从成员中公开。集合本身可能是也可能不是const,所以我无法根据它区分const_iterator 和iterator,但内部集合(模板)定义了常量。我认为使用enable_if<is_const<T 会实现这一点,但似乎没有。谢谢你的帮助
#include <cassert>
#include <type_traits>
#include <vector>
#include <algorithm>
template <typename ITEMS>
struct collection {
ITEMS& _items;
collection(ITEMS& items) : _items(items) {
}
auto find(int i) const {
return std::find(_items.begin(), _items.end(), i);
}
typename std::enable_if_t<std::is_const<ITEMS>::value>::const_iterator
end() const {
return _items.end();
}
typename std::enable_if_t<!std::is_const<ITEMS>::value>::iterator
end() const {
return _items.end();
}
};
template <typename ITEMS>
collection<ITEMS>
make_collection(ITEMS& items) {
return collection<ITEMS>(items);
}
int main() {
std::vector<int> ints = {1, 2, 3};
auto col = make_collection(ints);
const auto it = col.find(3);
assert(it != col.end());
const auto cints = ints;
auto ccol = make_collection(cints);
const auto cit = ccol.find(3);
assert(cit != ccol.end());
return 0;
}
编辑:仅使用 auto end() const { return _items.end(); } 有效,但我想了解为什么模板魔法不起作用。
【问题讨论】:
-
只需使用
auto或decltype。 -
没错,它有效,我想进一步了解为什么这种模板魔法不起作用
-
呃,
std::enable_if_t<std::is_const<ITEMS>::value>要么是void,要么是无效的。typename void::const_iterator毫无意义。