- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我试图更好地理解 decltype 以确定编译时表达式的类型。比方说,我用一个双变量来做:
#include <iostream>
#include <type_traits>
int main(){
double a;
typedef decltype(a) a_type;
typedef decltype((a)) ref_a_type;
typedef decltype(a)& o_ref_a_type;
a_type b;
ref_a_type c = b;
o_ref_a_type d = b;
if (std::is_same<decltype(b), double>::value) std::cout << "b is double\n";
if (std::is_same<decltype(c), double&>::value) std::cout << "c is double&\n";
if (std::is_same<decltype(d), double&>::value) std::cout << "d is double&\n";
}
如果我没有理解错的话,这些观点应该是正确的:
a
是左值,
decltype(a)
返回double&
,否则返回double
。 因此,decltype((a))
和 decltype(a)&
在这种情况下是等价的,但并不总是等价的,例如,如果 a
不是变量:
typedef decltype((5)) ref_a_type;
typedef decltype(5)& o_ref_a_type;
那么这两种类型不等价(ref_a_type
是 int
而 o_ref_a_type
是 int&
,因为额外的括号在这种情况下是无用的)。有人可以对此做出更好的解释吗?我应该使用第一种还是第二种方式?在我看来,第二种方式比第一种方式更具可读性和可理解性。
最佳答案
就 C++ 标准而言,decltype(e)
的规则非常清楚,所以我将复制它们(来自 [dcl.type.simple]):
For an expression
e
, the type denoted bydecltype(e)
is defined as follows:
(4.1) — ife
is an unparenthesized id-expression or an unparenthesized class member access (5.2.5),decltype(e)
is the type of the entity named bye
. If there is no such entity, or if e names a set of overloaded functions,the program is ill-formed;
(4.2) — otherwise, ife
is an xvalue,decltype(e)
isT&&
, whereT
is the type ofe
;
(4.3) — otherwise, ife
is an lvalue,decltype(e)
isT&
, whereT
is the type of e;
(4.4) — otherwise,decltype(e)
is the type ofe
.
所以按顺序看你的例子:
decltype(a)
: a
是一个未加括号的id-expression,所以这只是 a
: double
的类型。decltype((a))
:现在它被括起来了,所以我们跳过第一个项目符号。 a
不是一个 xvalue,它是一个 lvalue,所以这是 double&
。decltype(a)&
: 这又是第一种情况,所以它是 double&
。decltype((5))
:这既不是id-expression(带括号或其他)、xvalue 或 lvalue - 它是 prvalue,所以我们转到最后一个项目符号以获取类型表达式:int
。decltype(5)&
:与最后一点相同,只是现在您明确添加了 &
,所以 int&
。Should I use the first or the second way?
这取决于您实际想要获得的类型。这两种方式的含义不同 - 您应该使用能够解决您要解决的直接问题的任何一种方式。
更一般地说,由于引用折叠规则,decltype(expr)&
始终是左值引用。
decltype((expr))
可以是非引用纯右值(如 decltype((5))
)、左值引用(如 decltype((a))
)或右值引用(如 decltype((std::move(a)))
)。
关于c++ - 左值的 decltype 括号语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36517596/
由 this question 触发,我想知道是否允许这样做: template T foo(){return T{};} struct bar {}; int main() { bar a
我正在尝试以一种通用的方式实现 group_by 方法,我可能已经实现了它(除了它不适用于 C 数组),但代码对我来说仍然很难看...... 有没有更简单的方法来做我想做的事(+让它适用于所有容器和
这个问题在这里已经有了答案: What is decltype with two arguments? (2 个答案) 关闭 7 年前。 我遇到了一个decltype(),有两个参数作为模板函数的返
这是问题的后续:What does the void() in decltype(void()) mean exactly? . decltype(void()) 编译得很好,void() 在这种情况
这是我第一次使用decltype,我不太确定我是否正确使用它。该代码确实编译并且似乎适用于像 char 和 int 这样的 POD。 但是,我想知道我是否会遇到更复杂的数据类型的任何问题 - 其他人警
我一直在使用解析为与声明相同类型的定义中的推导返回类型。这有效: template struct Cls { static std::size_t f(); }; template declt
我发现它们是不同的,并且语言标准规定了每个语句应该检索什么样的类型(变量和表达式之间的差异)。但我真的很想知道为什么这两种类型应该不同? #include int x=0; decltype((x))
关于 decltype(x) 和 decltype((x)) 之间的区别,我已经读过很多遍了。一个例子如下。 x is the name of a variable, so decltype(x) i
我有一个简单的模板化包装器结构,其成员函数在其模板类型的对象上调用 .error()。 template struct Wrapper { T t; decltype(auto) f
decltype(auto) 和 decltype(returning expression) 作为函数(模板)的返回类型 if expr 有什么区别在这两种情况下都使用不带括号? auto f()
我在想 decltype((x)) 给出了 & 引用类型,但是一些实验表明还有其他事情: #include int main(){ int x = 0; decltype((x)) r
例如,简单的恒等仿函数: template class identity { public: constexpr auto operator ()(T && i) -> decltype(s
这个问题在这里已经有了答案: 关闭10 年前。 Possible Duplicate: decltype and parenthesis 我在维基百科上找到了这个: auto c = 0;
// g++ 7.3 template struct td; int main() { int a = 1; td t1; td t2; return 0; } 编译结果如下: 错误:
这确实是一个 C++14 问题。而且它的理论性多于实践性。 有时您会零碎地构建一个函数的结果: int f( int x, int y ) { int a; //... re
我试图检测成员函数 baz() 的存在在模板参数中: template struct ImplementsBaz : public std::false_type { }; template stru
考虑以下代码:(Ideone) struct S { int a() {return 0;} decltype(a()) b() {return 1;} }; 它给了我以下错误: er
(如果您是 C++11 专业人士,请跳至粗体段落。) 假设我想编写一个模板方法,该方法调用并返回传递的对象的结果,该对象的类型是模板参数: template ReturnType doSomethin
代码 #include int main() { int a=3; int *p=&a; decltype (a) k1; decltype (*p) k2;
我是 C++ 新手。我正在尝试学习 decltype 的概念。我在网上看到这段代码。我将 decltype(s1.size()) 更改为 int,代码工作正常。 decltype(s1.size())
我是一名优秀的程序员,十分优秀!