gpt4 book ai didi

c++ - 为指向集合的指针重载开始/结束是个好主意吗

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:38:20 26 4
gpt4 key购买 nike

我很喜欢免费的新概念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)
有什么问题吗?模板?是否存在由于某种原因而失败的情况?

最佳答案

如果你这样做,你将不能再使用为数组重载的 std::begin()std::end():

Container c[2] = { };
std::accumulate(begin(c), end(c), 0);

这不应该编译,因为你不能将 c[i] 添加到 0,但它可以编译,因为 begin(Container*) 选择了重载而不是通用的 std::begin(T (&)[N]) 一个。

再举个例子:

Container c[2] = { };
auto dist = std::distance(begin(c), end(c));

这应该设置 dist=2,因为数组有两个元素,但是您得到的是 dist=3 因为 end(*c) - begin( *c) 等于 3。

关于c++ - 为指向集合的指针重载开始/结束是个好主意吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13918046/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com