我真的很喜欢自由begin
end
编写更通用的算法和数据结构的新概念。目前,有时我必须区分调用begin(range)
和begin(*range)
类型何时将对集合的引用作为指针进行区分。我考虑是否总是为我自己的集合类型的指针提供开始/结束的重载是否是一个好主意。
struct Container {
int values[3];
};
const int* begin(const Container& c);
const int* end(const Container& c);
const int* begin(const Container* c);
const int* end(const Container* c);
template<typename Range>
int Sum(const Range& range)
{
return std::accumulate(begin(range), end(range), 0);
}
int main(void)
{
Container c = {1, 2, 3};
std::cout << Sum(c);
std::cout << Sum(&c);
}
如果这是一个好主意,为什么不为此提供一个模板:
template<typename Range>
auto begin(const Range* r) -> decltype(begin(*r)){
using std::begin;
return begin(*r);
}
template<typename Range>
auto end(const Range* r) -> decltype(end(*r)) { /* ... */ }
int main(void)
{
Container c = {1, 2, 3};
std::vector<int> v = {1, 2, 3}
std::cout << Sum(c);
std::cout << Sum(&c);
std::cout << Sum(v);
std::cout << Sum(&v);
}
如果这是一个好主意,为什么标准库不定义它?
我的问题是template<typename R>
auto begin(const R* r)
:模板有什么问题吗?是否存在由于某种原因而失败的情况?