8

假设我Utility在文件中有一个类utility.h

class Utility {
public:
    static double longDescriptiveName(double x) { return x + 42; }
};

然后我发现我经常使用这个功能longDescriptiveName(...)。因此,当我喝了太多咖啡时,就像一个不负责任的 C++ 程序员一样,我创建了一个新文件utilitymacros.h并在其中添加以下内容:

#define ldn Utility::longDescriptiveName

现在,我将其包括在我使用"utilitymacros.h"的任何地方,我的内心充满了喜悦,因为输入 3 个字母与 28 个字母相比更加方便。*.cppldn(...)

问题:有比 with 更安​​全(更合适)的方法#define吗?

我注意到在包含 boost 标头之后我必须包含“utilitymacros.h”,我显然不喜欢它,因为它是冲突的标志(尽管我得到的 Boost 错误对于冲突是什么并不十分清楚) .

说明 1:关于代码可读性

如果您可能会说这会对代码的可读性产生负面影响,我向您保证不会,因为它是一小组经常使用的函数。一个广为人知的例子是stoifor stringToInteger。另一个是pdfforprobabilityDensityFunction等。因此,如果我想执行以下操作,stoi我认为更具可读性:

int x = stoi(a) + stoi(b) + stoi(c) + stoi(d);

比:

int x = Utility::stringToInteger(a) + Utility::stringToInteger(b)
        + Utility::stringToInteger(c) + Utility::stringToInteger(d);

或者:

int x = Utility::stringToInteger(a);
x += Utility::stringToInteger(b);
x += Utility::stringToInteger(c);
x += Utility::stringToInteger(d);

说明 2:编辑器宏

我使用 Emacs 作为我选择的 IDE 和 Kinesis 键盘,所以您知道我使用了大量的键盘宏、自定义键盘快捷键,以及实际修改我在编辑器中看到的内容与实际存储在 h/cpp 文件中的内容。但是,我仍然觉得在一些选择的情况下使用函数缩写的简单性和视觉可读性(如上所述)确实是我正在寻找的结果(这当然受一定程度的影响)。

4

6 回答 6

14

inline您可以编写将调用转发到实际函数的函数,而不是宏:

inline double ldn(double x)
{
   return Utility::longDescriptiveName(x);
}

这肯定比宏安全。

于 2012-12-30T16:14:50.203 回答
7

您可以使用函数参考:

double (&ldn)(double) = Utility::longDescriptiveName;
于 2012-12-30T16:15:27.887 回答
3

在你的文本编辑器中配置一个片段/宏/类似的东西怎么样?这样你只需要输入 ldn 或类似的东西,代码就不必通过预处理器运行,以后很难找到错误。

于 2012-12-30T16:13:29.023 回答
2

我不知道这是否有帮助,但我认为部分问题可能是使用了过于笼统的命名空间(或类名,在这种情况下),例如Utility.

如果不是Utility::stringToInteger,我们有

namespace utility {
  namespace type_conversion {
    namespace string {
      int to_int(const std::string &s);
    }
  }
}

然后该函数可以像这样在本地使用:

void local_function()
{
  using namespace utility::type_conversion::string;

  int sum = to_int(a) + to_int(b) + to_int(c) + to_int(d);
}

类似地,如果使用类/结构和静态函数(这可能有充分的理由),我们有类似的东西

strut utility {
  struct type_conversion {
    struct string {
      static int to_int(const std::string &s);
    };
  };
};

并且本地函数看起来像这样:

void local_function()
{
  typedef utility::type_conversion::string str;

  int sum = str::to_int(a) + str::to_int(b)
              + str::to_int(c) + str::to_int(d);
}

我意识到我并没有告诉你任何你不知道的语法。它更多地提醒人们,命名空间和类的组织和结构本身在使代码更具可读性(和可写性)方面发挥着重要作用。

于 2012-12-30T16:51:20.843 回答
2

一种替代方法是重命名您的函数并将其放在命名空间而不是类中,因为它无论如何都是静态的。utility.h变成

namespace Utility {
    // long descriptive comment
    inline double ldn(double x) { return x + 42; }
}

然后你可以using namespace Utility;输入你的客户端代码。

我知道有很多风格指南说短名称是一件坏事,但我不明白遵循某种风格然后规避它的意义。

于 2012-12-31T15:22:07.680 回答
0

您可以使用别名模板(C++11 起)。

  using shortName = my::complicate::function::name;
于 2021-06-09T14:29:27.437 回答