C++11支持新的函数语法:
auto func_name(int x, int y) -> int;目前,此函数将声明为:
int func_name(int x, int y);新的风格似乎还没有被广泛采用(比如在gcc的文章中)
然而,这种新风格是否应该在新的C++11程序中到处都是首选的,或者只在需要的时候才使用呢?
就我个人而言,在可能的情况下我更喜欢旧的风格,但具有混合风格的代码库看起来相当丑陋。
发布于 2012-06-27 04:28:01
在某些情况下,必须使用尾随返回类型。最值得注意的是,如果指定了lambda返回类型,则必须通过尾随返回类型指定。此外,如果您的返回类型使用要求参数名称在作用域内的decltype,则必须使用尾随返回类型(不过,通常可以使用declval<T>来解决后一个问题)。
尾随返回类型确实有其他一些次要的优点。例如,考虑使用传统函数语法的非内联成员函数定义:
struct my_awesome_type
{
typedef std::vector<int> integer_sequence;
integer_sequence get_integers() const;
};
my_awesome_type::integer_sequence my_awesome_type::get_integers() const
{
// ...
}在类名出现在::get_integers之前之前,成员typedefs不在作用域中,因此我们必须重复两次类限定。如果我们使用尾随返回类型,我们不需要重复类型的名称:
auto my_awesome_type::get_integers() const -> integer_sequence
{
// ...
}在这个例子中,这并不是什么大问题,但是如果你有很长的类名或者类模板的成员函数没有被内联定义,那么它在可读性上会有很大的不同。
在C++Now 2012的"Fresh Paint"会议上,Alisdair Meredith指出,如果你一直使用尾随返回类型,所有函数的名称都会整齐地排列在一起:
auto foo() -> int;
auto bar() -> really_long_typedef_name;我在CxxReflect中的任何地方都使用过尾随返回类型,所以如果您正在寻找一致地使用它们的代码的示例,您可以查看那里(例如,the type class)。
发布于 2012-06-28 05:44:40
除了其他人所说的之外,尾随返回类型还允许使用this,否则不允许使用
struct A {
std::vector<int> a;
// OK, works as expected
auto begin() const -> decltype(a.begin()) { return a.begin(); }
// FAIL, does not work: "decltype(a.end())" will be "iterator", but
// the return statement returns "const_iterator"
decltype(a.end()) end() const { return a.end(); }
};在第二个声明中,我们使用了传统风格。但是,由于该位置不允许使用this,因此编译器不会隐式使用它。因此,a.end()使用静态声明的a类型来确定它将调用哪个end重载的vector<int>,这最终是非常量版本。
发布于 2017-01-12 23:05:50
另一个优点是,当函数返回指向函数的指针时,尾随返回类型的语法更具可读性。例如,比较
void (*get_func_on(int i))(int);使用
auto get_func_on(int i) -> void (*)(int);然而,人们可能会争辩说,只需为函数指针引入类型别名,就可以实现更好的可读性:
using FuncPtr = void (*)(int);
FuncPtr get_func_on(int i);https://stackoverflow.com/questions/11215227
复制相似问题