简体   繁体   中英

What is the rationale behind ADL for arguments whose type is a class template specialization

I've spent some time trying to realize why my code doesn't compile and I've realized that in C++ Argument Dependent Lookup uses template typename arguments to determine name lookup scope.

#include <string>
#include <functional>

namespace myns {

    template<typename T>
    struct X
    {};

    template<typename T>
    auto ref(T) -> void
    {}

} // namespace myns

auto main() -> int
{
    ref(myns::X<int>{});
    ref(myns::X<std::string>{}); // error: call to 'ref' is ambiguous
}

So the former ref call compiles, because for myns::X<int> only myns::ref is considered, while the latter doesn't compile because it finds myns::ref() as well as std::ref

My question is how this can be useful? Why would I need this? Do you have any ideas, examples? For now I can only see drawbacks like in the example above, where it introduces unneeded ambiguity.

Suppose you put all the things into your own namespace, including a user-defined class, and a function which takes std::vector as the parameter. ie

namespace myns {

    struct X {};

    template<typename T>
    auto my_func(const std::vector<T>&) -> void
    {}

} // namespace myns

then you can take advantage of the fact that ADL also considers the types provided as template arguments and just write:

my_func(std::vector<myns::X>{});

on the other hand:

my_func(std::vector<int>{});        // error, can't find my_func
myns::my_func(std::vector<int>{});  // fine

Get back to your original question, the lesson here is don't use names from standard libraries, it just makes codes confusing.

In one word: reuse. It allows you to use useful components from other libraries, and still have ADL applied.

For instance:

namespace my_stuff {
  class my_class {
    // Something useful here
  };

  void process(std::unique_ptr<my_class> item);
}

Now you can write code naturally, as you would when working with the class directly:

process(std::make_unique<my_class>());

If it wasn't the case, you'd need to roll out your own smart pointer, in your own namespace, just to facilitate good coding idioms and ADL.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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