C++11-清除返回值语法和decltype关键字
C++11 - Clearing out Return Value Syntax and decltype Keyword
从这里开始阅读,这段C++11代码对我来说似乎很奇怪:
template <typename Builder>
auto
makeAndProcessObject (const Builder& builder) -> decltype( builder.makeObject() )
{
auto val = builder.makeObject();
// do stuff with val
return val;
}
我有几个问题:
1( decltype(builder.makeObject(((是否在执行实际调用之前再调用一次makeObject函数?
2( 如果不是,并且在编译时一切都是已知的(所以它是一个增强的宏(,为什么下面的语法无效,我需要新的返回值语法?
//WRONG
template <typename Builder>
decltype( builder.makeObject() )
makeAndProcessObject (const Builder& builder)
{
auto val = builder.makeObject();
// do stuff with val
return val;
}
[奖励问题-回答后获得+1分]3( 在这个问题中,一个人问为什么他的代码没有编译,答案是成员函数makeObject缺少一个"const"说明符。我得到了答案,但不知道为什么需要const。
以下申报的内容
template <typename Builder>
auto
makeAndProcessObject (const Builder& builder) -> decltype( builder.makeObject() )
如果const Builder&对象引用具有const makeObject还是非常量makeObject?decltype(builder.makeObject(((部分必须只找出函数的返回类型,它不应该关心函数是否修改了作为参数传递的对象!
通常,C++中的东西在声明之后才可用。在您的示例中,您试图在声明生成器之前使用它:
template <typename Builder>
decltype( builder.makeObject() ) // using builder here
makeAndProcessObject (const Builder& builder) // but builder isn't declared until here
{
auto val = builder.makeObject();
// do stuff with val
return val;
}
添加函数返回类型的新语法是为了解决这个问题。
template <typename Builder>
auto // dummy return type, meaning we will give it later
makeAndProcessObject (const Builder& builder) // declaring builder here
-> decltype( builder.makeObject() ) // using builder here -- no problem.
{
auto val = builder.makeObject();
// do stuff with val
return val;
}
至于你的额外问题:对于语言来说,说你必须给decltype一个有效的表达式要简单得多,而不是有另一组关于哪些参数对decltype有效的规则。
-
没有。
decltype
创建一个未赋值的上下文,就像sizeof
一样。编译器只查看类型信息,而不查看其他信息。 -
不能在前导返回类型中使用参数。
decltype( builder.makeObject() ) makeAndProcessObject (const Builder& builder)
由于CCD_ 3是未知标识符。这就是创建尾随返回类型的原因。
- 在未评估的上下文中,类型信息很重要。并且
this
参数是否为const
是类型信息的一部分。如果decltype
不进行过载解析,它将毫无用处。如果您从未见过基于成员函数的const
的重载,那么这可能没有意义,但可能有两个具有相同名称和参数的函数,一个用于对象的const
视图,另一个用于非const
。返回类型可以不同(实际上,它们通常因const
而不同(
答案:
1( 不是。decltype
只在编译时计算表达式的类型,在运行时不计算表达式的值。因此,decltype
被称为"未评估的上下文",因为它是sizeof
和noexcept
。
2( 请注意,在此声明中
template <typename Builder>
decltype( builder.makeObject() )
makeAndProcessObject (const Builder& builder)
编译器在看到声明const Builder& builder
之前先看到builder
,而对于已接受的声明,在确定返回类型时,编译器已经解析了所需的所有信息。auto
关键字告诉编译器在稍后有更多信息可用时,将给出返回类型。
3( 问题不在于申报
template <typename Builder>
auto
makeAndProcessObject (const Builder& builder) -> decltype( builder.makeObject() )
它实际上与功能体有关。更准确地说,以下行:
auto val = builder.makeObject();
由于builder
是const Builder&
,因此只能在builder
上调用const
方法,而且最初makeObject()
不是其中之一。然后用const
的方法解决了这个问题。
更新:阅读Ben Voigt的答案后。与我上面所说的相反,声明中也存在问题,因为它使用了decltype(builder.makeObject())
,并且我在函数体中使用的参数也适用于此。
- Visual Studio 2015:Extern "C" 和 "export" 关键字
- C++中的"inline"关键字
- 如何确保C++函数在定义之前声明(如override关键字)
- 在VS2010-VS2015下编译时,如何使用decltype作为较大类型表达式的LHS
- C++decltype和圆括号-为什么
- 在for循环中使用auto vs decltype(vec.size())来处理字符串的向量
- 如何从"decltype()"获取函数参数的数量<funtion>?
- Confusion: decltype vs std::function
- 谷歌模拟和覆盖关键字
- decltype(1, t) 应该是 l 值引用吗?(编译器不同意)
- 结构体 S { int align; } 之间的区别;(struct 关键字后的名称)和 struct { int al
- 如果全局变量默认是外部变量,为什么要添加"extern"关键字?
- 当我从下面的代码中删除关键字 virtual 时,它可以正常工作,否则会出现错误。在这里"virtual"字的意义是什么?
- 为什么"delete"关键字不删除节点?
- 在 c++ 中正确定义"this"关键字?
- 这个额外的关键字在这个 c++ 类声明中是什么意思?
- 在 typedef 内部使用 const 关键字和在 typedef 外部使用 const 关键字之间有区别吗?
- C++ - 为什么这里需要'template'关键字?
- C++函数的关键字?
- C++11-清除返回值语法和decltype关键字