我一直在尝试清理继承的代码库。它广泛使用包含尾随返回类型的模板函数。它还包含许多非模板化非成员函数的函数指针。在清理过程中,我发现代码等同于Visual Studio 2013下的以下代码:
#define function typedef auto
function Kernel (int, int) -> int;
struct Transform
{
Kernel* kernel;
char* description;
};
Transform add_transform { add, "add" };
这种typedef在C ++ 11标准中是否有效?
虽然我个人避免像瘟疫这样的#defines(特别是当用于创建像这些'函数'这样的新语言功能时),但鉴于项目中流行返回类型的普遍存在,团队认为这会使代码库显着增加可读的。
答案 0 :(得分:4)
尾随返回类型语法是C ++ 11中的新增功能,只要您可以编写函数类型,它就是有效的。 auto <function>(<parameters>) -> <result>
只是一种写作<result> <function>(<parameters>)
的奇特方式(<result>
可以引用<parameters>
的好处)。
这意味着typedef auto Kernel (int, int) -> int;
完全有效,与typedef int Kernel (int, int);
完全相同。然后可以在函数声明或函数指针中使用Kernel
typedef。
答案 1 :(得分:3)
使用宏重新发明C ++语法可能很诱人。你可能会想出一些像这样酷的东西,然后想“哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇
这种方法最基本的问题是它对于发明宏的人来说更具可读性,或者如果你不太了解C ++。如果您完全理解typedef auto fn(int) -> int
的含义,那么您将无法再找到有用的宏。语法已经足够清楚了。
要复杂化,你要介绍宏的所有无数问题。您正在全面劫持function
符号名称 - 无论范围如何。现在您无法再使用std::function
了。你不仅不能使用它,而且它会抛出一些根本不具描述性的讨厌的编译器错误。编译器将尝试解析std::typedef auto
,这是无意义的。
答案 2 :(得分:1)
它是有效的,因为auto(int, int) -> int;
是一个函数声明符,除了它缺少一个名字。名称Kernel
是typedef
说明符用于创建类型名称的标识符。由于存在尾随返回类型,auto
将替换为int
,它变为int(int, int)
。如果你想说服你的团队这样做是徒劳的,那么考虑一下你可以采用相同语法的方法:
using Kernel = int(int, int);
using Kernel = auto(int, int) -> int;
typedef auto Kernel(int, int) -> int;
这些在语义上都是等效的,并且避免使用宏。