C++ 什么';在C+;中定义短函数名别名最安全的方法是什么+;?

C++ 什么';在C+;中定义短函数名别名最安全的方法是什么+;?,c++,function,macros,alias,c-preprocessor,C++,Function,Macros,Alias,C Preprocessor,假设我在文件Utility.h中有一个类Utility: class Utility { public: static double longDescriptiveName(double x) { return x + 42; } }; 然后我发现我经常使用函数longDescriptiveName(…)。因此,像一个不负责任的C++程序员,当我喝了太多咖啡时,我创建了一个新的文件 UTILYMACROS.H./CUD>,并添加了以下内容: #define ldn Utility::l

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

class Utility {
public:
    static double longDescriptiveName(double x) { return x + 42; }
};
然后我发现我经常使用函数
longDescriptiveName(…)
。因此,像一个不负责任的C++程序员,当我喝了太多咖啡时,我创建了一个新的文件<代码> UTILYMACROS.H./CUD>,并添加了以下内容:

#define ldn Utility::longDescriptiveName
现在,我将
“utilitymacros.h”
包含在我使用
ldn(…)
的任何
*.cpp
中,我的心充满了喜悦,因为键入3个字母比键入28个字母方便多了

问题:有没有比使用
#define
更安全(更合适)的方法

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

澄清1:关于代码可读性

如果您可能会说这会对代码可读性产生负面影响,我向您保证不会,因为这是一组经常使用的函数。众所周知的一个例子是
stringToInteger
stoi
。另一个是
pdf
用于
概率密度函数
等。因此,如果我想执行以下操作,
stoi
在我看来更具可读性:

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

或:

澄清2:编辑器宏


我使用Emacs作为我选择的IDE和一个动态键盘,所以你知道我使用了大量的键盘宏、自定义键盘快捷键,以及实际修改我在编辑器中看到的内容和实际存储在h/cpp文件中的内容。不过,我还是觉得在一些特定情况下使用函数缩写的简单性和视觉可读性(如上所述)才是我想要的结果(这当然要受到一定程度的限制)。

在文本编辑器中配置snipbit/macro/类似的东西怎么样?这样,您只需键入ldn或类似的内容,代码就不必在预处理器中运行,以免以后很难找到错误。

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

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

这当然比宏更安全。

您可以使用函数引用:

double (&ldn)(double) = Utility::longDescriptiveName;

我不知道这是否有帮助,但我认为问题的一部分可能是使用了过于通用的名称空间(或类名,在本例中),例如
实用程序

如果不是
实用工具::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);
}
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);
}
类似地,如果使用类/结构和静态函数(这可能有很好的理由),我们有

strut utility {
  struct type_conversion {
    struct string {
      static 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);
}
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);
}

我意识到我没有告诉你任何你不知道的语法;这更像是提醒人们,名称空间和类本身的组织和结构在提高代码可读性(和可写性)方面起着重要作用。

另一种方法是重命名函数并将其放在名称空间而不是类中,因为它是静态的<代码>实用程序.h变为

namespace Utility {
    // long descriptive comment
    inline double ldn(double x) { return x + 42; }
}
然后,您可以使用名称空间实用程序放置
在您的客户端代码中


我知道有很多样式指南都说短名称是一件坏事,但我不认为遵循某种样式然后绕过它有什么意义。

您可以使用别名模板(从C++11开始)


另外,在C++11中,
auto&&ldn=Utility::longDescriptiveName这是非常惯用的。在任何情况下,
static
的优点是什么?@Potatoswatter:它位于头文件中<代码>静态
用于避免多个定义错误。@Nawaz
静态
用于定义具有相同名称的多个不同对象。最好使用
extern
。无论如何,通常首选未命名的命名空间。使用函数引用可能会影响函数调用的内联能力。我认为这不是一个好主意,因为它会损害代码的可读性。我会假设
pdf
是一种文件格式,并且会非常困惑。字符是免费的,不使用它们并不能拯救环境。也许短名称对你来说是可读的,但对其他人来说是很难的,即使它们在任何地方都被使用(尤其是)。在我的旧版本中,有很多3个字符的函数名,这是我退出那里的原因之一:代码太乱了。当然,不仅仅是因为函数和变量名,它也是其中的一部分。+1内联函数肯定更安全,因为有类型检查,我认为建议使用(C++风格)而不是#define(C风格和不太安全)。旁注:与宏不同,inline没有使用任何数据类型,这是通过使用带有inline的模板来实现的@Nawaz,我假设内联函数不是类
实用工具的一部分,对吗?在这种情况下,您是否建议将内联定义放在与
utility.h
相同的标题中,或者为它们创建一个单独的标题,如
utilityhelpers.h
?@LexFridman:是的。它在类
实用程序
之外。您可以将它放在同一个标题中,但在类之外。这取决于你。
  using shortName = my::complicate::function::name;