han*_*aad 6 c++ templates c++11
我真的很喜欢自由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);
}
Run Code Online (Sandbox Code Playgroud)
如果这是一个好主意,为什么不为此提供一个模板:
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);
}
Run Code Online (Sandbox Code Playgroud)
如果这是一个好主意,为什么标准库没有定义它?
我的问题是:template<typename R>
auto begin(const R* r)模板有什么问题吗?是否有任何因某种原因失败的情况?
如果这样做,您将无法再使用数组std::begin()并重载:std::end()
Container c[2] = { };
std::accumulate(begin(c), end(c), 0);
Run Code Online (Sandbox Code Playgroud)
这不应该编译,因为您无法添加c[i]到0,但它可以编译,因为begin(Container*)选择了重载而不是通用std::begin(T (&)[N])。
再举个例子:
Container c[2] = { };
auto dist = std::distance(begin(c), end(c));
Run Code Online (Sandbox Code Playgroud)
这应该设置dist=2,因为数组有两个元素,但你得到的是dist=3因为end(*c) - begin(*c)等于 3。
| 归档时间: |
|
| 查看次数: |
836 次 |
| 最近记录: |