c – 通过自由功能或成员功能进行扩展的机制

加载C库,包括的标准,允许您调整您的对象在库中使用.选择通常在同一命名空间中的成员函数或自由函数之间.

我想知道机制,并构建库代码用于调度一个调用其中一个“扩展”函数函数,我知道这个决定必须在编译时发生并涉及模板.以下运行时版本的psuedocode是不可能/无意义的,原因超出了这个问题的范围.

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"

上面的代码看起来像运行时代码:/.那么,图书馆如何找出一个类所在的命名空间,它如何检测三个条件,还有什么其他的陷阱是需要避免的.

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

!!赢得BOUNTY!

好的,根据史蒂夫的回答(和意见),ADL和SFINAE是编译时接线调度的关键.我已经把我的头放在ADL(原始)和SFINAE(再次粗暴的).但我不知道他们如何按照我认为应该的方式在一起.

我想看到一个如何将这两个结构放在一起的说明性示例,以便库可以在编译时选择是否调用对象中的用户提供的成员函数,或者在同一对象的命名空间中提供的用户提供的免费函数.这只能使用上面的两个结构来完成,没有任何类型的运行时调度.

让我们说这个对象被称为NS :: Car,这个对象需要提供MoveForward(int unit)的行为,作为c的成员函数.如果从对象的命名空间中获取行为,它可能看起来像MoveForward(const Car& car_,int units).让我们定义要调度移动器(NS :: direction d,const NS :: vehicle& v_)的函数,其中direction是枚举,而v_是NS :: car的基类.

解决方法

那么,我可以告诉你如何在编译时检测某个名字(和签名)的成员函数的存在.我的一个朋友在这里描述:

Detecting the Existence of Member Functions at Compile-Time

但是,这不会让你想去,因为它只适用于静态类型.因为你想传递一个“参考到车”,所以没有办法测试动态类型(引用后面的具体对象的类型)是否具有这样一个成员函数.

如果你为静态类型定居,那么还有另外一种方式来做一个非常相似的事情.
它实现“如果用户提供重载的自由功能,调用它,否则尝试调用成员函数”.它就像这样:

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”超载,
在与他的班级相同的命名空间中,所以它被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

编辑:再次阅读史蒂夫·杰西普的回答后,我意识到这基本上是他写的,只有更多的话:)

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...