【问题标题】:What is the purpose of a declaration like int (x); or int (x) = 10;像 int (x) 这样的声明的目的是什么?或 int (x) = 10;
【发布时间】:2014-11-09 19:28:25
【问题描述】:

如果您查看*declarator*s in §8/4 的语法,您会注意到noptr-declarator 可以写成(ptr-declarator),也就是说,它可以写成 (declarator-id),它验证标题中的声明。事实上,这段代码编译没有问题:

#include <iostream>
struct A{ int i;};
int (x) = 100;
A (a) = {2};
int main()
{
    std::cout << x << '\n';
    std::cout << a.i << '\n';
}

但是在声明中不涉及指针(指向数组或函数)时允许使用这些括号的目的是什么?

【问题讨论】:

  • 大概是因为要禁止它们需要更复杂的语法。
  • 这可能是一个解释。我没想到这个。
  • 同样,(42) 是一个有效的表达式,即使括号是不必要的。

标签: c++ c++11 language-lawyer variable-declaration


【解决方案1】:

这条规则适用于你的情况并不是故意的:它最终是保持语法简单的结果。没有理由禁止像您这样的声明,但是有很大的抑制因素使规则复杂化,尤其是当这些规则复杂时。

简而言之,如果您不想使用这种不必要的混淆语法,请不要使用。
C++ 很少强迫你编写可读的代码。

令人惊讶的是,在某些情况下括号可以挽救局面:

std::string foo();

namespace detail
{
    int foo(long); // Another foo

    struct Bar
    {
        friend std::string ::foo(); // Doesn't compile for obvious reasons.

        friend std::string (::foo)(); // Voilà!
    };
}

【讨论】:

  • 你能不能稍微解释一下friend std::string (::foo)();声明?我们实际上声明了什么以及为什么?
  • @DmitryFucintv:声明要声明foo 的实例,该实例在第一行中声明为结构Barfriend。要将函数声明为友元,您需要提供其返回类型和参数。但是说friend std::string foo() 是行不通的,因为对于不合格的使用,foo 被“另一个”foo 隐藏。因此,必须通过全局限定符 :: 来限定 foo。但这给出了显示的第一个表单,该表单在指定std::string 的(不存在的)成员时存在歧义。 ::foo 周围的一对括号用于避免歧义
【解决方案2】:

你问错问题了。正确的问题是:

不允许这样的声明的目的是什么?

答案是:没有

所以,考虑到这种语法被允许作为其他地方规则的副作用,这就是你得到的。

【讨论】:

  • 不允许这样声明的一个原因是,目前声明T(x);是声明x类型为T的变量,而不是x的函数转换表达式输入T(纯粹是因为它的副作用),这就是它的样子。
  • @jchl:“纯粹是因为它的副作用”这是你的问题
猜你喜欢
  • 2016-05-03
  • 2020-10-25
  • 2022-11-13
  • 2011-01-03
  • 2010-10-12
  • 2013-08-20
  • 2013-06-12
  • 2012-01-17
  • 2010-09-11
相关资源
最近更新 更多