简体   繁体   English

为非 std:: 命名空间内的距离启用 ADL,并回退到 std::distance

[英]Enabling ADL for distance within a non-std:: namespace, with a fallback to std::distance

My use-case is as follows - within a non-std:: namespace, a class has a templated member function which takes in 2 (templated) iterators as parameters, and part of the function call involves calling distance() on those iterators. My use-case is as follows - within a non-std:: namespace, a class has a templated member function which takes in 2 (templated) iterators as parameters, and part of the function call involves calling distance() on those iterators. The problem is, some containers have their own overload for distance() for their iterators.问题是,一些容器对于它们的迭代器有自己的 distance() 重载。 So if I specify std::distance, this is not sufficient.因此,如果我指定 std::distance,这还不够。 However because the class is not within the std:: namespace, the call to distance without the std:: qualifier will not resolve to std::distance on containers without their own distance() overload.但是,因为 class 不在 std:: 命名空间内,所以在没有 std:: 限定符的情况下调用 distance 将不会在没有自己的 distance() 重载的容器上解析为 std::distance。

How can I rework the problem (if possible) such that std::distance ends up getting called where necessary, but not when an overload exists for the iterator in question?我怎样才能重新处理问题(如果可能),以便 std::distance 最终在必要时被调用,但在所讨论的迭代器存在重载时不被调用?

Example code (not actual code):示例代码(不是实际代码):

namespace derp
{
   template <class iterator_t>
   int a_function(iterator_t t1, iterator_t t2)
   {
      int a = distance(t1, t2); // want to resolve to std::distance if, for example, iterator is from std::vector
      // Do stuff with a and t1/t2
      return a;
   }
}

Templating to std::vector etc is not possible, as there are too many std:: containers and it would cause code bloat.无法对 std::vector 等进行模板化,因为 std:: 容器太多,会导致代码膨胀。

The idiomatic way of doing so (commonly done with swap ):这样做的惯用方式(通常用swap完成):

namespace derp
{
   template <class iterator_t>
   int a_function(iterator_t t1, iterator_t t2)
   {
      using std::distance;
      int a = distance(t1, t2); // want to resolve to std::distance if, for example, iterator is from std::vector
      // Do stuff with a and t1/t2
      return a;
   }
}

With this construction, custom distance found in the namespace of iterator_t is preferred, but fallbacks to std::distance .使用这种结构,在iterator_t的命名空间中找到的自定义distance是首选,但回退到std::distance

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM