Kir*_*ran 8 c++ compiler-construction parsing parentheses
我对编译器对括号的解释感到困惑.有人可以解释在这种情况下究竟发生了什么吗?
施法:(int)a或int(a)
参数传递:
template <typename t>
int size(t (&)[n]){return n;}
Run Code Online (Sandbox Code Playgroud)
显然,可能存在许多不同的上下文,其中括号改变了含义或解释.有人可以解释幕后发生的事情吗?编译器如何知道如何在每个上下文中进行解释?是否有一般指导方针或是针对每个案例的具体规则?
谢谢
tem*_*def 22
Pedantic上尉救援!
如果你写
int(value)
Run Code Online (Sandbox Code Playgroud)
这就是所谓的显式类型转换,受§5.2.3的约束.确切的措辞说明了这一点
简单类型说明符(7.1.5)后跟带括号的表达式列表,在给定表达式列表的情况下构造指定类型的值.如果表达式列表是单个表达式,则类型转换表达式与相应的强制转换表达式(5.4)相同(在定义中,如果在意义上定义)
(我强调).所以这意味着
int(value)
Run Code Online (Sandbox Code Playgroud)
和
(int)value
Run Code Online (Sandbox Code Playgroud)
完全相同.您可以选择更容易编写的中的任何一个.
至于你的第二个问题,在你给模板和数组给出的例子中,我相信你打算写的是这样的.
template <typename T, size_t N>
size_t (T (&)[N]) {
return N;
}
Run Code Online (Sandbox Code Playgroud)
这里,N以及T一个模板参数,它允许您传入任何您想要的数组,同时让编译器填充N数组中的元素数.如果这看起来很混乱(究竟是T (&)[N]什么?),那是因为这个函数接受了一个类型的参数T (&)[N].为了使这更容易阅读,让我们给这个参数一个名字,如下所示:
template <typename T, size_t N>
size_t (T (&array)[N]) {
return N;
}
Run Code Online (Sandbox Code Playgroud)
我认为这使得阅读更容易一些.但这个宣言意味着什么?
T (&array)[N]
Run Code Online (Sandbox Code Playgroud)
这声明了一个名为的变量array,它是对具有T精确N元素的s 数组的引用.您确实可以声明对数组的引用,就像您可以声明指向数组的指针一样.这在实践中并不常见,但在这个特定的模板中,成语是让编译器在尝试将数组与模板参数匹配时推断出数组大小的好方法.
在这种情况下括号的原因是,如果你写
T& array[N]
Run Code Online (Sandbox Code Playgroud)
编译器会将其解析为"一个称为对象array数组的变量N,每个对象都是一个T&.但是,C++规范明确禁止引用数组,这将是非法的.括号明确消除歧义.这类似于函数指针 - 你写的
void (*functionPointer)()
Run Code Online (Sandbox Code Playgroud)
代替
void *functionPointer()
Run Code Online (Sandbox Code Playgroud)
为了使编译器认识到*这意味着functionPointer是一个指针,而不是返回的功能void *.
至于编译器如何确定何时以各种方式处理括号,规则相当复杂,实际上有一些情况下编译器不会以预期的方式解析表达式.其中一种情况通俗地称为"最令人烦恼的解析",其中编译器将对象构造看起来像一个函数原型.作为示例,此代码:
vector<int> v();
Run Code Online (Sandbox Code Playgroud)
难道不是创建一个vector<int>名为v使用默认构造函数初始化.相反,它将此视为一个函数原型,用于调用v一个不带参数的函数,并产生一个vector<int>!但是,如果你要写
vector<int> v(10);
Run Code Online (Sandbox Code Playgroud)
然后编译器可以毫不含糊地推断出这是一个vector<int>传递10为构造函数参数的声明,因为它无法被视为函数原型.规范的§6.8和§8.2通过说任何可以作为声明处理的东西来处理这些情况,并且任何可以被视为函数原型的东西都是如此.
数组上下文中括号的情况(即T (&array)[N])由不同的逻辑处理,因为在您声明变量或定义类型需要显式括号的参数的上下文中,不存在歧义关于你的意图,因为从上下文中可以清楚地看到你为了声明变量而命名一个类型.
总结一下 -
T(value)和(T)value相同.T (&array)[N]是为了防止编译器绑定&到T而不是array按预期绑定.希望这可以帮助!
| 归档时间: |
|
| 查看次数: |
13972 次 |
| 最近记录: |