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"

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

我的问题的动机是让我能够在库中找到调度块,并能够在自己的代码中使用构造。因此,详细的答案将有所帮助。

!!赢取奖金!

好的,根据Steve的回答(和评论),ADL和SFINAE是在编译时连接调度程序的关键结构。我对ADL(本来就是)和SFINAE(又是基本介绍)一清二楚。但是我不知道他们如何按照我认为的方式协调工作。

我想看一下如何将这两个结构放在一起的说明性示例,以便库可以在编译时选择是在对象中调用用户提供的成员函数,还是在同一对象的 namespace 中调用用户提供的自由函数。仅应使用上述两个结构来完成此操作,而不能进行任何类型的运行时调度。

假设有问题的对象称为NS::Car,并且该对象需要提供MoveForward(int units)的行为,作为c的成员函数。如果要从对象的 namespace 中获取行为,则它可能看起来像MoveForward(const Car & car_, int units)。让我们定义要分派(dispatch)mover(NS::direction d, const NS::vehicle & v_)的函数,其中direction是一个枚举,v_是NS::car的基类。

最佳答案

好吧,我可以告诉您如何在编译时检测特定名称(和签名)的成员函数的存在。我的一个 friend 在这里描述了它:

Detecting the Existence of Member Functions at Compile-Time

但这并不会带您去哪里,因为它仅适用于静态类型。由于您要传递“车辆引用”,因此无法测试动态类型(引用后面的具体对象的类型)是否具有这种成员函数。

如果您选择使用静态类型,那么还有另一种方法可以做类似的事情。
它实现了“如果用户提供了一个重载的free函数,则调用它,否则尝试调用成员函数”。它是这样的:

namespace your_ns {

template <class T>
void your_function(T const& t)
{
    the_operation(t); // unqualified call to free function
}

// in the same namespace, you provide the "default"
// for the_operation as a template, and have it call the member function:

template <class T>
void the_operation(T const& t)
{
    t.the_operation();
}

} // namespace your_ns

这样,用户可以提供自己的“the_operation”重载,
在与他的类相同的 namespace 中,因此ADL可以找到它。当然
用户的“the_operation”必须比您的默认值“更专业”
实现-否则调用将是模棱两可的。
实际上,这不是问题,因为所有限制因素
参数的类型比对任何内容的const引用要多
“更专业”。

例子:
namespace users_ns {

class foo {};

void the_operation(foo const& f)
{
    std::cout << "foo\n";
}

template <class T>
class bar {};

template <class T>
void the_operation(bar<T> const& b)
{
    std::cout << "bar\n";
}

} // namespace users_ns

编辑:再次阅读史蒂夫·杰索普(Steve Jessop)的答案后,我意识到这基本上就是他写的内容,只是多了几句话:)

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

10-12 00:12
查看更多