函数标题中的箭头运算符 (->)
Arrow operator (->) in function heading
我遇到了以下代码:
template <typename T, typename T1> auto compose(T a, T1 b) -> decltype(a + b) {
return a+b;
}
有一件事我无法理解:
我在哪里可以找到箭头运算符(->
(在函数标题中的含义?
我想纯粹从逻辑上讲,->
运算符确定一种类型,auto
将被推导出来,但我想直截了当。我找不到任何信息。
在 C++11 中,函数声明有两种语法:
返回类型标识符(
参数声明... )
和
auto
标识符(
参数声明... )
->
return_type
它们是等效的。现在,当它们是等效的时,您为什么要使用后者?好吧,C++11引入了这个很酷的decltype
的东西,可以让你描述表达式的类型。因此,您可能希望从参数类型派生返回类型。所以你试试:
template <typename T1, typename T2>
decltype(a + b) compose(T1 a, T2 b);
编译器会告诉你,它不知道decltype
参数中的a
和b
是什么。那是因为它们仅由参数列表声明。
通过使用已声明的declval
和模板参数,可以轻松解决此问题。喜欢:
template <typename T1, typename T2>
decltype(std::declval<T1>() + std::declval<T2>())
compose(T1 a, T2 b);
只是现在变得非常冗长。所以提出并实现了替代声明语法,现在你可以写
template <typename T1, typename T2>
auto compose(T1 a, T2 b) -> decltype(a + b);
而且它不那么冗长,范围界定规则不需要更改。
C++14更新:C++14也只允许
auto
标识符(
参数声明... )
只要函数在使用前完全定义,并且所有return
语句都推导为同一类型。如果要在源文件中隐藏正文,则->
语法对于公共函数(在标头中声明(仍然有用。很明显,这不能用模板来完成,但是有一些具体的类型(通常通过模板元编程派生(很难以其他方式编写。
用简单的英语来说,它告诉返回类型是 a
和 b
之和的推断类型。
除了 decltype 和 declval 用法之外,您还可以使用类中定义的返回类型来定义类成员函数,而无需再次提供Class::
范围解析前缀。
例:
class SomeLongClassname
{
public:
typedef std::shared_ptr<Node> PNode;
PNode make_node ();
};
选择:
SomeLongClassname::PNode SomeLongClassname::make_node () { ... }
或
auto SomeLongClassname::make_node () -> PNode { ... }
第二种形式有时更清晰。
相关文章:
- 为什么比较运算符如此快速
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 使用C++中的模板和运算符重载执行矩阵运算
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 增量运算符与后缀混淆
- 一个关于在C++中重载布尔运算符的问题
- 运算符C++ "delete []"仅删除 2 个前值
- 模板类无法识别友元运算符
- 我可以使用条件运算符初始化C风格的字符串文字吗
- 关闭||运算符优化
- 通过继承类使用来自不同命名空间的运算符
- C++Cast运算符过载
- 如何使用AngelScript注册SFML Vector2运算符
- 重载元组索引运算符-C++
- 如何使用重载的相等(==)运算符向测试用例添加描述
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 多个If语句与使用逻辑运算符计算条件的单个语句的比较
- 布尔比较运算符是如何在C++中工作的
- 重载运算符new[]的行为取决于析构函数
- 是否需要使用 - &gt;运算符在C 中调用成员函数时