为了更好地理解std::解密,我想出了以下“玩具模型”代码:
#include <iostream>
#include <typeinfo>
struct Bar
{
Bar(double); // some non-default ctor
double f(); // some function of which return type we want to get
};
using Barref = Bar&&; // emulating std::declval<Bar>()
int main()
{
// FUNKY, compiles in g++, not in clang++
// error: unexpected type name 'Barref': expected expression
decltype(Barref.f()) x; // (1)
std::cout << typeid(x).name() << std::endl; // i -> int INCORRECT
// OK, just for testing
decltype(std::declval<Bar>().f()) y; // (2)
std::cout << typeid(y).name() << std::endl; // d -> double CORRECT
}因此,我将类型为Barref作为Bar&&类型的rvalue引用,并在(1)中的decltype表达式中使用它。如果我正确理解,这正是std::declval所做的,它是一个非定义函数,它返回对其模板参数的rvalue引用。
template<class T>
typename std::add_rvalue_reference<T>::type declval();因此,我们可以在未评估的上下文(如decltype )中使用后者。当类型有一个非默认的ctor时,它是有用的,并且我们希望获得一些关于某个成员函数的类型信息,而不需要构造对象。我认为下面的代码就是这么做的。g++5.1 编译它,但是x是int类型的(而不是double,正如我所猜测的)。然而,clang++ 编译代码失败说
错误:意外类型名称'Barref':预期表达式解密类型(barreg.f()) x;
我的问题:
decltype(Barref.f())的使用真的和使用decltype(std::declval<Bar>().f())一样吗?这似乎有点奇怪,因为Barref.f()实际上不是一个函数的返回值(即使没有计算)。我意识到,即使是decltype(Bar.f())也编译(g++),没有任何类型别名。x的类型是int而不是double?发布于 2015-06-16 00:31:43
减到
struct Meow {};
int main(){
decltype(Meow.purr()) d;
}这是明显无效的代码,但GCC 5.1和主干接受它。除了“臭虫”,没什么可说的。有趣的是,两者都正确地拒绝了
struct Meow {};
decltype(Meow.purr()) d;https://stackoverflow.com/questions/30856911
复制相似问题