让我们假设我有以下Data类:
struct Data {
char foo[8];
char bar;
};下面的函数my_algorithm,它接受一对char * (类似于STL算法):
void my_algorithm(char *first, char *last);对于Data的foo数据成员,而不是像这样调用my_algorithm():
Data data;
my_algorithm(data.foo, data.foo + 8);我可以使用std::begin()和std::end()方便函数模板:
my_algorithm(std::begin(data.foo), std::end(data.foo));我想要实现类似于Data的bar数据成员的东西。也就是说,不要写:
my_algorithm(&data.bar, &data.bar + 1);我想写这样的东西:
my_algorithm(begin(data.bar), end(data.bar));因此,我为本例定义了以下两个普通(非模板)函数:
char* begin(char& c) { return &c; }
char* end(char& c) { return &c + 1; }这样我就可以编写如下代码:
Data data;
using std::begin;
using std::end;
my_algorithm(begin(data.foo), end(data.foo)); // ok - std::begin()/std::end()
my_algorithm(begin(data.bar), end(data.bar)); // Error!!!使用上面的using声明,我希望std::begin()/std::end()和::begin()/::end()分别处于相同的重载集中。由于函数::begin()和::end()是后一次调用的完美匹配,而且它们不是模板,所以我希望对my_algorithm()的最后一次调用能够匹配它们。不过,我们根本不考虑一般的功能。结果编译失败,因为std::begin()和std::end()与调用不匹配。
从根本上说,后一种调用就像我写的那样:
my_algorithm(begin<>(data.bar), end<>(data.bar));也就是说,重载解析过程只考虑函数模板(即std::begin()/std::end()),而不考虑普通函数(即::begin()/::end())。
只有当我完全限定对::begin()/::end()的调用时,它才能正常工作
my_algorithm(::begin(data.bar), ::end(data.bar));我在这里错过了什么?
发布于 2019-06-03 17:41:54
问题的标题是“重载std::begin()”。重载只有在同一范围内才有可能。也就是说,您不能重载来自不同范围的名称。在另一个范围内,我们只能努力帮助查找名称。本质上,这里的“使用std ::begin”声明隐藏了::begin的代码。有关参考,请参见S.Lippman:
作为两个不同名称空间的成员的函数不会相互重载。 使用声明的范围。在使用声明中引入的名称符合正常范围规则。在外部作用域中定义相同名称的实体将被隐藏。
一旦参数是char和char是基本类型,就不应该考虑参数依赖的查找--正如注释中提到的--没有与基本类型相关联的命名空间。同样,问题是:“我漏掉了什么?”--因此答案只集中在理由上--建议可能过于宽泛。
https://stackoverflow.com/questions/56432036
复制相似问题