这是一个容器:
namespace container_namespace
{
template <class element_type, class element_allocator_type = std::allocator<element_type> >
class container
{
// stuff
class iterator
{
// stuff
};
};
}
我在上面的什么地方定义了 advance(InputIt &, Distance N)
以便允许在我的 main() 中使用
通过 ADL(参数相关查找):advance()
int main(int argc, char **argv)
{
using namespace std;
using namespace container_namespace;
container<int> c;
// Add elements to c here
container<int>::iterator it = c.begin();
advance(it, 20);
}
是否选择了自定义 advance()
函数而不是 std::advance
?
我已经看到在迭代器类中定义自定义 advance()
函数的示例,以及在命名空间中定义的示例,其中仅在迭代器类中声明了友元。哪项对于启用 ADL 是正确的?其他关于 SO 的例子在这一点上并不清楚。
最佳答案
我认为最安全的方法是将它定义为 container
或 iterator
的 friend
。这样定义的函数被放到namespace container_namespace
中,这样就可以被ADL找到:
namespace container_namespace {
template <class element_type, class element_allocator_type = std::allocator<element_type> >
class container {
//...
template <typename Diff>
friend void advance(iterator&, Diff) {
//...
}
};
}
另一种选择是直接在 namespace container_namespace
中定义它。通过这种方式,您可以为所有容器提供通用实现和/或实现标记分派(dispatch)以处理不同的迭代器类别,就像在 std::advance
实现中所做的那样:
namespace container_namespace {
template <typename Iter, typename Diff>
void advance(Iter&, Diff) {
std::cout << "ADL-ed advance\n";
}
}
这种方法的问题在于,当 std::advance
在范围内时,它会导致歧义(感谢@TC):
DEMO
另请注意,您不能按如下方式定义 advance
:
namespace container_namespace {
template <typename element_type, typename element_allocator_type, typename Diff>
void advance(typename container<element_type, element_allocator_type>::iterator&, Diff) {
std::cout << "ADL-ed advance\n";
}
}
因为它的第一个参数的类型会失败(参见 Non-deduced contexts )。
关于C++ - 如何在自定义模板化数据容器中的迭代器上使用 advance() 启用 ADL?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35144435/