记录std::function参数的最佳实践

3
在使用std::function声明类型时,我发现无法为模板参数分配参数名称。例如,我发现这种普通函数指针类型声明:
typedef void (*ArcCallback)(
  void *object, 
  double x_start, double y_start, 
  double x_finish, double y_finish, 
  double x_center, double y_center, 
  bool counterclockwise);

要比这个std::function类型声明更易读:

typedef std::function<void(
  void *,
  double, double,
  double, double,
  double, double,
  bool)> ArcCallback;

尽管使用 std::function 很灵活(例如,可以分配lambda或std::bind调用的结果),但我错过了参数名称。当然,我可以在 std::function 声明中添加注释,但结果很笨拙。更重要的是,我认为IDE不会使用这些注释来提供参数提示。
其他有经验的C++开发者如何记录对 std::function 模板参数的目的?是否有已广泛使用此类类型的库所设置的先例?

我对接受这个问题的答案感到犹豫。AnT指出我的前提是错误的——我已经可以用与函数指针参数相同的方式命名我的模板参数。Josh Kelley描述了一种风格更好的命名函数参数的方法。无论哪种方式,参数都会被命名,但是Josh的方式会产生我所希望的IDE反馈,并且参数名称在调用点可见。因此,我接受了Josh的答案。 - Tim Crews
2个回答

5

对于这段特定代码而言,问题并不是std::function没有好的方法来记录参数,而是8个参数对于任何函数来说都可能过于复杂。引入额外的类型可以在很大程度上改善这种情况。

typedef void* CallbackObject;

struct Point {
  double x;
  double y;
};

enum CircularDirection {
  CLOCKWISE,
  COUNTERCLOCKWISE
};

struct ArcCallbackParam {
  CallbackObject object;
  Point start;
  Point finish;
  Point center;
  CircularDirection direction;
};

typedef std::function<void(const ArcCallbackParam&)> ArcCallback;

编辑: 我意识到这并没有直接回答你的问题。为了回答你的问题,我不知道除了注释参数之外是否有任何“解决方案”,但是添加类型和typedef可以帮助很多。


"对于任何函数来说,8个参数可能太多了。" - edmz
从IDE的角度来看,这样做的好处是强制创建一个具有字段名称的结构,使得在编码时可以获得提示。而且,结果代码中字段的目的更加明确。 - Tim Crews
@black - 说得好,尽管15-20年前的C API可能不是设计接口的最佳示例。 - Josh Kelley

4

你原来的 ArcCallback 类型定义中的参数名称仅用于自我记录目的。既然你有一个使用“冗余”参数名称进行自我记录目的的习惯,为什么不在 std::function 的情况下也这样做呢?

typedef std::function<void (
  void *object, 
  double x_start, double y_start, 
  double x_finish, double y_finish, 
  double x_center, double y_center, 
  bool counterclockwise)> ArcCallback;

该语言不禁止这样做。

1
很有趣;我不知道这是可能的。我刚刚确认它可以在VC++13中工作。如果这符合标准,那么我可能会开始在参数列表较短时给模板参数命名。至少对于Visual Studio IDE而言,以这种方式命名参数并不能带来任何IDE提示的好处。 - Tim Crews

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接