快速C++代表

Ash*_*Ash 19 c++ delegates one-definition-rule language-lawyer

我知道以下C++代理方法:

.与纯虚函数的接口
.Boost.Function
.最快可能的C++代表
.不可能快速的C++代表
.快速C++代表
.Fast C++ Delegate:Boost.Function'drop-in'替换和多播

每个都有其优点和缺点.有些更快,有些更灵活,有些更丰富,有些更符合标准,有些更便携,但我个人觉得自己喜欢第三种:Sergey Ryazanov的不可能快速的C++代表.但问题是他的代表不具备可比性:

我的代表无法比较.未定义比较运算符,因为委托不包含指向方法的指针.存根函数的指针在各种编译单元中可以不同.

读者回答了哪一个:

"在各种编译单元中,指向存根函数的指针可能不同." AFAIK,这不是真的.编译器需要重复使用在不同编译单元中生成的模板函数(我确信 - 但我认为Borland曾违反此规则).我认为这是因为类(不在"无名"命名空间中)使用外部链接,并且使用存根函数的方式总是会阻止它们被内联(尽管这不应该是一个问题,因为它取了函数的地址将强制生成非内联版本,并且链接器执行的"外部链接"将消除除一个类似命名的函数之外的所有函数(假定它们并且标准要求它们相同))...

如果您定义一个转换单元(cpp文件)的模板函数,然后在另一个转换单元中以不同方式定义相同的函数,则两个版本中只有一个将使其成为最终的可执行文件.(这实际上违反了"一个定义规则",但适用于GCC,至少......不确定MSVC.)重点是:[存根]的地址在不同的单位中是相同的.

如果您发现MSVC属实,我会敦促您更新文章(包括比较功能) - 如果MSVC是标准授权,就此而言.

现在这篇文章已有四年了,作者在过去三年左右没有回复任何评论,所以我想知道上述评论是否有任何优点,以及这个具体实施是否确实可以改为支持比较.C++标准是否明确禁止此类使用?如果是这样,那么最近的编译器是否在这方面符合标准?

谢谢.

Pav*_*aev 12

代码既符合标准又很好.我没有看到他违反ODR的任何地方,并且具有相同模板参数的函数模板的所有实例化都应该具有"相同的地址"(在某种意义上指向函数的指针应该都相等) - 如何实现这一点并不重要.ISO C++ 03 14.5.5.1 [temp.over.link]更详细地描述了规则.

因此,可以以一致且可移植的方式在那里定义比较.