我花了一些时间试图了解为什么我的代码没有编译,我已经意识到在C ++中 Argument Dependent Lookup 使用模板typename参数来确定名称查找范围。
#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
}
所以前面的ref调用编译,因为myns::X<int>
仅考虑myns::ref
,而后者不编译,因为它找到myns::ref()
以及std::ref
}
我的问题这是如何有用的?我为什么需要这个?你有什么想法,例子吗?现在我只能看到上面例子中的缺点,它会引入不必要的歧义。
答案 0 :(得分:7)
假设您将所有内容放入您自己的命名空间,包括用户定义的类,以及以std::vector
为参数的函数。即。
namespace myns {
struct X {};
template<typename T>
auto my_func(const std::vector<T>&) -> void
{}
} // namespace myns
然后你可以利用ADL也考虑作为模板参数提供的类型的事实,然后写:
my_func(std::vector<myns::X>{});
另一方面:
my_func(std::vector<int>{}); // error, can't find my_func
myns::my_func(std::vector<int>{}); // fine
回到原来的问题,这里的教训是不使用标准库中的名称,只会让代码混乱。
答案 1 :(得分:3)
总之一句:重用。它允许您使用其他库中的有用组件,并且仍然应用了ADL。
例如:
namespace my_stuff {
class my_class {
// Something useful here
};
void process(std::unique_ptr<my_class> item);
}
现在,您可以自然地编写代码,就像直接使用类一样:
process(std::make_unique<my_class>());
如果不是这样的话,你需要在你自己的命名空间中推出自己的智能指针,只是为了促进良好的编码惯用语和ADL。