c++ - 通过自由函数或成员函数进行扩展的机制

标签 c++ oop templates compile-time library-design

大量 C++ 库(包含标准)允许您调整对象以在库中使用。通常在同一命名空间中的成员函数或自由函数之间进行选择。

我想了解库代码的机制和构造,该库代码用于分派(dispatch)将调用这些“扩展”函数之一的调用,我知道这个决定必须在编译期间发生并且涉及模板。以下运行时伪代码是不可能的/无意义的,原因超出了这个问题的范围。

if Class A has member function with signature FunctionSignature
    choose &A.functionSignature(...)
else if NamespaceOfClassA has free function freeFunctionSignature
    choose freeFunctionSignature(...)
else
    throw "no valid extension function was provided"

上面的代码看起来像运行时代码:/。那么,库如何确定类所在的命名空间,如何检测这三个条件,还有哪些其他需要避免的陷阱。

我提出问题的动机是让我能够在库中找到分派(dispatch) block ,并能够在我自己的代码中使用这些结构。因此,详细的答案会有所帮助。

!!赢得赏金!!

好的,根据 Steve 的回答(和评论)ADL 和 SFINAE 是在编译时连接调度的关键结构。我有我的头脑 arround ADL(原始)和 SFINAE(再次粗鲁)。但我不知道他们是如何以我认为应该的方式协调在一起的。

我想看一个说明性的例子,说明如何将这两个结构放在一起,以便库可以在编译时选择是调用对象中用户提供的成员函数,还是调用对象中用户提供的自由函数对象的命名空间。这应该只使用上面的两个构造来完成,没有任何类型的运行时分派(dispatch)。

假设有问题的对象叫做NS::Car,这个对象需要提供MoveForward(int units)的行为,作为c的一个成员函数.如果行为是从对象的命名空间中获取的,它可能看起来像 MoveForward(const Car & car_, int units)。让我们定义要调度 mover(NS::direction d, const NS::vehicle & v_) 的函数,其中 direction 是一个枚举,而 v_ 是 NS 的基类: :car.

最佳答案

库在运行时不会做任何这些,调度是由编译器在编译调用代码时完成的。根据称为“参数相关查找”(ADL)(有时称为“Koenig 查找”)的机制规则,在与其中一个参数相同的命名空间中找到自由函数。

在您可以选择实现自由函数或成员函数的情况下,可能是因为库为调用成员函数的自由函数提供了模板。然后,如果您的对象通过 ADL 提供了同名函数,它将比实例化模板更匹配,因此将首先被选中。正如Space_C0wb0y所说,他们可能会使用SFINAE来检测模板中的成员函数,并根据它是否存在来做一些不同的事情。

您无法更改 std::cout << x; 的行为通过向 x 添加成员函数,所以我不太清楚你的意思。

关于c++ - 通过自由函数或成员函数进行扩展的机制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5299843/

相关文章:

C++ std::locale ("en") 在 iOS 上抛出异常

c++ - 将 QClipboard 传递给 QML

c++ - Boost.Spirit 将#include 功能添加到计算器示例中

c++ - 我可以将什么用作 RAII+关注点分离的标准 C++ 基类

java - 获取xml数据

javascript - OOP 方法中是否可以知道 ajax 调用何时完成

c++ - 模板参数重新声明

javascript - 从 C++ 函数返回字符串到 JavaScript

java - 具有 Java 绑定(bind)功能的简单模板库

c++ - 模板模板参数的模板特化