相关疑难解决方法(0)

为什么有注入的类名?

最近,我看到了一个奇怪的C++特性:注入类名.

class X { };
X x1;
class X::X x2; // class X::X is equal to X
class X::X::X x3; // ...and so on...
Run Code Online (Sandbox Code Playgroud)

但我无法弄清楚为什么这个功能是必要的.有没有需要此功能的练习?

我听说旧C++中不存在这个功能.然后,什么时候介绍?C++ 03?C++ 11?

c++

142
推荐指数
1
解决办法
6321
查看次数

为什么C++允许我们在声明变量时用括号括起变量名?

例如,声明如下:

int (x) = 0;
Run Code Online (Sandbox Code Playgroud)

甚至是:

int (((x))) = 0;
Run Code Online (Sandbox Code Playgroud)

我偶然发现了这一点,因为在我的代码中我碰巧有一个类似于下面的片段:

struct B
{
};

struct C
{
  C (B *) {}
  void f () {};
};

int main()
{
  B *y;
  C (y);
}
Run Code Online (Sandbox Code Playgroud)

显然,我想构造一个对象C,然后在它的析构函数中做一些有用的东西.但是,当它发生时,编译器将其C (y);视为y带有类型的变量声明,C因此它会输出有关y重新定义的错误.有趣的是,如果我把它写成C (y).f ()或类似的东西C (static_cast<B*> (y))将按预期编译.当然,最好的现代解决方法是{}在构造函数调用中使用.

因此,当我在那之后发现,可以声明变量之类的int (x) = 0;甚至是,int (((x))) = 0;但我从未见过任何人实际使用这样的声明.所以我很感兴趣 - 这种可能性的目的是什么,因为现在我看到它只创造了类似于臭名昭着的"最令人烦恼的解析"的情况,并没有添加任何有用的东西?

c++ most-vexing-parse

81
推荐指数
2
解决办法
4725
查看次数

注入的类名编译器差异

考虑以下代码:

struct foo{};

int main() {
    foo::foo a;
}
Run Code Online (Sandbox Code Playgroud)

我希望这个格式正确,foo通过[class]/2中的规则声明一个类型的变量(N4140,强调我的):

一个类名被插入在其中后立即宣布的范围类的名字能够被看见. 类名也被插入到类本身的范围 ; 这被称为注入类名.出于访问检查的目的,inject-class-name被视为公共成员名称.

clang 3.6.0同意我的意见,编译上面的代码没有适用的警告-Wall -pedantic.

gcc 5.2.0 不同意,提供以下错误消息:

main.cpp: In function 'int main()':
main.cpp:5:5: error: 'foo::foo' names the constructor, not the type
   foo::foo a;
Run Code Online (Sandbox Code Playgroud)

无论注入的类名称的嵌套有多深,例如,上述情况都适用foo::foo::foo::foo.

是否存在强制该构造在该上下文中被解释为构造函数的规则,或者这是一个gcc错误?或者我是否错误地解释标准报价?

c++ gcc clang language-lawyer c++14

22
推荐指数
2
解决办法
3741
查看次数

类模板的注入类名称

灵感来自这个答案中的代码.考虑:

template<class>
class A { };

int main()
{
    A<float> a(A<float>::A<int>());
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是代码

  1. A<float>::A格式错误,因为命名构造函数(根据§3.4.3.1[class.qual]/p2)并且不能在此上下文中使用(加上<int>完全无法解析),或者
  2. 良好的,与A<float>::A作为注射类名,用作模板的名称(§14.6.1[temp.local]),使得A<float>::A<int>装置完全一样A<int>,并且a被声明为函数(由于最烦恼的解析)?

g ++说1. clang说2,ICC 13也是如此.哪个编译器正确?

c++ templates language-lawyer

17
推荐指数
1
解决办法
906
查看次数

在标准(C++ 14)中它表示以下两个声明是等效的吗?

struct A{};
int A;
struct A a;
struct A::A b;
Run Code Online (Sandbox Code Playgroud)

上面的最后两个声明是等价的.它们都声明了类型A的对象.在标准中我可以找到或推断出这个吗?

c++ language-lawyer c++14

8
推荐指数
1
解决办法
225
查看次数

为什么decltype(class :: class :: class :: member)有效

我意外地注意到这段代码编译并正常工作:

struct M { int some_int; };
static_assert(std::is_same<
                   decltype(M::M::M::M::some_int) /* <- this */,
                   int>::value, "Types must be int");
Run Code Online (Sandbox Code Playgroud)

为什么这是正确的(decltype(M::M::M::M::some_int) <=> decltype(M::some_int))?

还有哪些其他构造可以使用这种模式class::class::...::member

编译器:用于x86的Microsoft(R)C/C++优化编译器版本19.00.23824.1

c++ decltype c++11

8
推荐指数
2
解决办法
302
查看次数