gpt4 book ai didi

c++ - 如何自记录模板库类调用的回调函数?

转载 作者:IT老高 更新时间:2023-10-28 21:57:14 25 4
gpt4 key购买 nike

我有一个函数 User::func() (回调)将由模板类( Library<T> )调用。

在第一次迭代开发中,大家都知道func()仅用于单一目的。
几个月后,大多数成员忘记了func()是为了。
经过一些重度重构,func()有时会被某些编码人员删除。

一开始,我并不认为这是一个问题。
但是,在我多次遇到这种模式之后,我觉得我需要一些应对措施。

问题

如何优雅地记录它? (可爱&&简洁&&没有额外的CPU成本)

示例

这是一个简化的代码:-
(现实世界的问题是分散在 10 多个库文件和 20 多个用户文件和 40 多个函数周围。)

图书馆.h

template<class T> class Library{
public: T* node=nullptr;
public: void utility(){
node->func(); //#1
}
};

User.h

class User{
public: void func(){/** some code*/} //#1
//... a lot of other functions ...
// some of them are also callback of other libraries
};

ma​​in.cpp

int main(){
Library<User> li; .... ; li.utility();
}

我的糟糕解决方案

1。评论/文档

作为第一个解决方法,我倾向于添加这样的评论:-

class User{ 
/** This function is for "Library" callback */
public: void func(){/** some code*/}
};

但它很快就会变脏——我必须将它添加到每个类的每个“func”中。

2。重命名“func()”

在实际情况下,我倾向于像这样为函数名称添加前缀:-

class User{ 
public: void LIBRARY_func(){/** some code*/}
};

很明显,但是函数名现在很长了。
(尤其是当 Library -class 的类名较长时)

3。具有“func()=0”的虚拟类

我正在考虑创建一个抽象类作为回调接口(interface)。

class LibraryCallback{ 
public: virtual void func()=0;
};
class User : public LibraryCallback{
public: virtual void func(){/** some code*/}
};

它给人的感觉是func()用于 something-quite-external:)
但是,我必须牺牲虚拟调用成本(v-table)。
在性能关键的情况下,我负担不起。

4。静态函数

(来自 Daniel Jour 在评论中的想法,谢谢!)

差不多 1 ​​个月后,这是我的使用方法:-

图书馆.h

template<class T> class Library{
public: T* node=nullptr;
public: void utility(){
T::func(node); //#1
}
};

User.h

class User{
public: static void func(Callback*){/** some code*/}
};

ma​​in.cpp

int main(){
Library<User> li;
}

它可能更干净,但仍然缺少自文档。

最佳答案

func不是 User 的功能.它是 User 的一个功能。 - Library<T>耦合。

将其放入 User如果它在 Library<T> 之外没有明确的语义使用是个坏主意。如果它确实有明确的语义,它应该说明它的作用,删除它应该是一个明显的坏主意。

将其放入 Library<T>不能工作,因为它的行为是 T 的函数在 Library<T> .

答案是两个都不放。

template<class T> struct tag_t{ using type=T; constexpr tag_t(){} };
template<class T> constexpr tag_t<T> tag{};

现在在 Library.h :

struct ForLibrary;
template<class T> class Library{
public: T* node=nullptr;
public: void utility(){
func( tag<ForLibrary>, node ); // #1
}
};

User.h :

struct ForLibrary;
class User{
/** This function is for "Library" callback */
public:
friend void func( tag_t<ForLibrary>, User* self ) {
// code
}
};

或者只是把它放到与 User 相同的命名空间中, ForLibrary 相同的命名空间:

friend func( tag_t<ForLibrary>, User* self );

删除前func ,您将追踪到 ForLibrary .

它不再是 User 的“公共(public)接口(interface)”的一部分,所以不会弄乱它。它要么是 friend (助手),要么是 User 相同命名空间中的自由函数或 Library .

您可以在需要 Library<User> 的地方实现它而不是 User.hLibrary.h , 特别是如果它只使用 User 的公共(public)接口(interface).

这里使用的技术是“标签调度”、“参数依赖查找”、“友元函数”以及优先使用自由函数而不是方法。

关于c++ - 如何自记录模板库类调用的回调函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43445184/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com