2010-11-25 24 views
9

为什么发明了依赖于参数的查找(ADL)?难道只有我们可以写cout << stuff而不是std::operator<<(cout, stuff)?如果是这样的话,为什么ADL不限于运营商而不是所有功能?为什么发明了依赖于参数的查找?

如果C++有一些其他方式来执行内置和用户定义类型的通用输出,例如类型安全的printf通过可变参数模板,可以阻止引入ADL吗?

回答

11

ADL的发明,使接口原理:

接口原理

对于类X,所有功能,包括免费的功能,这两个

  • “提“X和
  • ”随附“X

在逻辑上是X的一部分,因为它们形成X的界面

退房香草萨特关于这一专题的优秀Guru of the Week的一部分。

1

是的,它主要是为操作员发明的。但它也使您能够将非成员功能添加到班级的界面中。这是我非常喜欢的一个非常强大的东西。这不仅限于运营商。例如,你可能想为你的vector类定义一个cross_product函数 - 你知道我的意思:)

3

它被发明允许函数多态性。这个想法是,该函数是一个动词(如“印刷”),它只有一个含义。仍然可以有不同的实现取决于什么动词适用(如int和float和std :: string)。

所以我们想要一个词的概念,但几个实施取决于它的应用。

它适用于什么是参数。所以我们需要一种方法来在几个不同类型的参数上使用同一个词 - 其中需要参数类型相关的实现。

试着用printInt(),printString(),printFloat()函数编写一个复杂的连接,你会看到明显的冗长。

另一个原因是它允许检查最重要的实现是否可用于参数类型。如果没有可用的实现(甚至不是泛型 - 使用模板),那么编译器会尽快阻止您,并让您知道它没有为给定参数实现动词。

6

如果是这样,为什么ADL不限于运营商而不是所有功能?

为什么要人为地限制它? ADL可能很难实现(当与C++的超载规则结合使用时),但它是一种非常有用的技术。首先,它也可以在函数上工作,这使得使用其他名称空间而不用导入整个名称空间变得更加容易。

典型的例子,该SeqAn library

using seqan::String; 
String<Char> url = "http://www.seqan.de/"; 
std::cout << "The URL " << url << " has length " << length(url) << std::endl; 

请注意,我用的功能seqan::length而不必限定它的全名。无论如何ADL发现它。 SeqAn库过度使用这样的名称空间范围函数,并且将每个用法与名称空间名称相加都是不切实际的。同样,导入名称空间通常也不可取。

许多其他图书馆(如Boost的大多数图书馆)也是如此。


而且我相信,这不是立即被委员会实现。

+1

没错。没有ADL,你会写' :: ... * *很多*。或者说,你可能会使用'使用命名空间',这将有效地禁用该语言的一个非常好的功能。 – DevSolar 2010-11-25 12:40:10

4

为什么不限制给操作员?

让我们来看一个简单的遗传算法:

template <typename FwdIt, typename T> 
FwdIt remove(FwdIt first, FwdIt last, T const& value) 
{ 
    using std::swap; 

    FwdIt result = first; 
    for (; first != last; ++first) 
    if (!(*first == value)) swap(*result++, *first); 
    return result; 
} 

它是如何与自定义类型和自己的swap版本的工作?感谢ADL

这就是Sutter所说的接口原理,正如丹尼尔所说。