我最近遇到了以下深奥的代码.
int main(){(([](){})());}
Run Code Online (Sandbox Code Playgroud)
按如下方式重新格式化以使其更具可读性:
int main(){
(([](){})()); // Um... what?!?!
}
Run Code Online (Sandbox Code Playgroud)
但我无法理解如何(([](){})())
有效的代码.
谷歌对这种全符号搜索没有多大帮助.但它在Visual Studio 2010中编译并且不输出任何内容.没有错误,也没有警告.所以它看起来像有效的代码.
我从未见过任何在Javascript和C函数指针之外如此奇怪的有效代码.
有人可以解释这是如何有效的C++?
我无法找到对decltype的一个很好的解释.请告诉我,作为一名初学程序员,它的作用以及它为何有用.
例如,我正在读一本提出以下问题的书.有人可以向我解释答案和原因,以及一些好的(初级)例子吗?
当代码完成时,每个变量的类型和每个变量的值是多少?
Run Code Online (Sandbox Code Playgroud)int a = 3, b = 4; decltype(a) c = a; decltype((b)) d = a; ++c; ++d;
逐行解释将非常有帮助.
我正在维基百科上C++11
阅读关于类型推断功能的这篇文章.
有一个例子,我引述:
#include <vector>
int main() {
const std::vector<int> v(1);
auto a = v[0]; // a has type int
decltype(v[1]) b = 1; // b has type const int&, the return type of
// std::vector<int>::operator[](size_type) const
auto c = 0; // c has type int
auto d = c; // d has type int
decltype(c) e; // e has type int, the type of the entity named by c
decltype((c)) f = …
Run Code Online (Sandbox Code Playgroud) 当有人问decltype(a)
及 和之间的区别时decltype((a))
,通常的回答是 -a
是一个变量,(a)
是一个表达式。我觉得这个答案并不令人满意。
首先,a
也是一个表达式。主要表达式的选项包括 -
更重要的是, decltype 的措辞非常非常明确地考虑了括号:
For an expression e, the type denoted by decltype(e) is defined as follows:
(1.1) if e is an unparenthesized id-expression naming a structured binding, ...
(1.2) otherwise, if e is an unparenthesized id-expression naming a non-type template-parameter, ...
(1.3) otherwise, if e is an unparenthesized id-expression or …
Run Code Online (Sandbox Code Playgroud) 鉴于:
decltype(auto) f1()
{
int x = 0;
return x; // decltype(x) is int, so f1 returns int
}
decltype(auto) f2()
{
int x = 0;
return (x); // decltype((x)) is int&, so f2 returns int&
}
Run Code Online (Sandbox Code Playgroud)
(摘自Scott Meyer的Effective Modern C++).
现在,如果我找到了正确的段落,则第7.1.5.2节 C++标准的简单类型说明符[dcl.type.simple]说:
如果e是id-expression或类成员访问(5.2.5 [expr.ref]),则decltype(e)被定义为由e命名的实体的类型
而该部分的例子是:
struct A { double x; }
const A* a = new A();
decltype((a->x)); // type is const double&
Run Code Online (Sandbox Code Playgroud)
现在,我想知道为什么被decltype((x))
推断出来是int&
在书中.
在什么情况下,额外的分组括号会破坏C++中的内容(特别是C++ 11)?由于这里不相关的原因,我最终在一个表达式上有一个额外的,不必要的一组parens围绕它,我发现C++ 11 typeinfo函数is_same
确定它是一个不同于没有括号的相同代码.这是一个有点莫名其妙的行为的简要示例:
#include <iostream>
using namespace std;
int main()
{
string s = "foo";
cout << std::is_same<decltype(s), decltype(string("foo"))>::value;
cout << std::is_same<decltype(s), decltype((s))>::value;
cout << std::is_same<decltype((s)), decltype(string("foo"))>::value;
cout << std::is_same<decltype((s)+"x"), decltype(string("foo")+"x")>::value;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
此代码打印"1001",这似乎表示中间两行中的额外parens导致表达式为不同类型,但在较大的表达式中使用该括号表达式使其再次成为相同类型.另一方面,如果我使用typeid获取类型的名称,typeid(s)
并且typeid((s))
似乎产生相同的东西.
我现在已经解决了眼前的问题,但我仍然不明白为什么会发生这种情况; 搜索"双括号c ++"之类的东西似乎没有出现任何相关内容(主要是有关运算符重载的页面,以及仅在特定关键字后激活的编译器扩展).
那么:这到底是怎么回事?为什么类型s
不同(s)
?
很简单的问题,我无法用谷歌搜索出答案。
例如:
int a = 0;
int& b = x;
int&& c = 1;
decltype((a)) x; // what is the type of x?
decltype((b)) y; // what is the type of y?
decltype((c)) z; // what is the type of z?
Run Code Online (Sandbox Code Playgroud)
我不确定我应该为x,y和z分配一些值以获得不同的结果。
编辑:
根据双括号下面的站点将示例int
转换为参考:https :
//github.com/AnthonyCalandra/modern-cpp-features#decltype
int a = 1; // `a` is declared as type `int`
int&& f = 1; // `f` is declared as type `int&&`
decltype(f) g = 1; // `decltype(f) is `int&&`
decltype((a)) …
Run Code Online (Sandbox Code Playgroud)