带有尾随 return 类型的 c++11 typedef 函数指针
c++11 typedef function pointer with trailing return type
我一直在尝试清理继承的代码库。它广泛使用了包含尾随 return 类型的模板函数。它还包括许多指向非模板化、非成员函数的函数指针。在清理过程中,我发现在 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(尤其是当用于创建像这些 'functions' 这样的新语言功能时),但考虑到项目中尾随 return 类型的普遍存在,团队认为这将使代码库更具可读性。
尾部 return 类型语法是 C++11 中的新语法,它在任何可以编写函数类型的地方都有效。 auto <function>(<parameters>) -> <result>
只是一种奇特的写法 <result> <function>(<parameters>)
(好处是 <result>
可以引用 <parameters>
)。
这意味着 typedef auto Kernel (int, int) -> int;
完全有效,并且与 typedef int Kernel (int, int);
的含义完全相同。 Kernel
typedef 可用于函数声明或函数指针声明。
使用宏重新发明 C++ 语法可能很诱人。你可能想出像这样很酷的东西,然后想 "wow that's so much more clear".
这种方法最根本的问题是它只对发明宏的人或对 C++ 不够了解的人更具可读性。如果您完全可以理解 typedef auto fn(int) -> int
的含义,那么您将不再发现您的宏有任何用处。语法已经很清楚了。
为了使事情复杂化,您引入了宏的所有无数问题。您正在全面劫持 function
符号名称 - 无论范围如何。现在您不能再使用 std::function
。您不仅不能使用它,而且还会抛出一些令人讨厌的编译器错误,这些错误根本不是描述性的。编译器将尝试解析 std::typedef auto
这是无稽之谈。
它是有效的,因为 auto(int, int) -> int;
是一个函数声明符,只是它缺少名称。名称 Kernel
是 typedef
说明符用来创建 type-name 的标识符。由于 trailing-return-type 存在,auto
被 int
取代,变成 int(int, int)
。如果您想说服您的团队这是徒劳的,请考虑实现相同语法的方法:
using Kernel = int(int, int);
using Kernel = auto(int, int) -> int;
typedef auto Kernel(int, int) -> int;
这些在语义上都是等价的,并且避免使用宏。
我一直在尝试清理继承的代码库。它广泛使用了包含尾随 return 类型的模板函数。它还包括许多指向非模板化、非成员函数的函数指针。在清理过程中,我发现在 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(尤其是当用于创建像这些 'functions' 这样的新语言功能时),但考虑到项目中尾随 return 类型的普遍存在,团队认为这将使代码库更具可读性。
尾部 return 类型语法是 C++11 中的新语法,它在任何可以编写函数类型的地方都有效。 auto <function>(<parameters>) -> <result>
只是一种奇特的写法 <result> <function>(<parameters>)
(好处是 <result>
可以引用 <parameters>
)。
这意味着 typedef auto Kernel (int, int) -> int;
完全有效,并且与 typedef int Kernel (int, int);
的含义完全相同。 Kernel
typedef 可用于函数声明或函数指针声明。
使用宏重新发明 C++ 语法可能很诱人。你可能想出像这样很酷的东西,然后想 "wow that's so much more clear".
这种方法最根本的问题是它只对发明宏的人或对 C++ 不够了解的人更具可读性。如果您完全可以理解 typedef auto fn(int) -> int
的含义,那么您将不再发现您的宏有任何用处。语法已经很清楚了。
为了使事情复杂化,您引入了宏的所有无数问题。您正在全面劫持 function
符号名称 - 无论范围如何。现在您不能再使用 std::function
。您不仅不能使用它,而且还会抛出一些令人讨厌的编译器错误,这些错误根本不是描述性的。编译器将尝试解析 std::typedef auto
这是无稽之谈。
它是有效的,因为 auto(int, int) -> int;
是一个函数声明符,只是它缺少名称。名称 Kernel
是 typedef
说明符用来创建 type-name 的标识符。由于 trailing-return-type 存在,auto
被 int
取代,变成 int(int, int)
。如果您想说服您的团队这是徒劳的,请考虑实现相同语法的方法:
using Kernel = int(int, int);
using Kernel = auto(int, int) -> int;
typedef auto Kernel(int, int) -> int;
这些在语义上都是等价的,并且避免使用宏。