构造函数中的无限循环,不带或不带

CJA*_*LEE 61 c++ recursion constructor const

我在这里做了一个测试,但输出是一个没有结束的循环,我不知道为什么.

实际上,我正在做另一个测试,但是当我写这个时,我不明白循环是如何发生的.它反复输出"ABC".

#include <map>
#include <string>
#include <iostream>

class test
{
public:
   std::map <int, int> _b;
   test();
   test (std::map<int, int> & im);
   ~test();
   };

test::test()
{
  std::cout<<"abc";
  _b.clear();
  _b[1]=1;
  test(_b);
}

test::test(std::map <int, int>& im)
{
   std::cout<<im[1];
}

test::~test() {};

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

tem*_*def 94

这里的问题是编译器解释

test(_b);
Run Code Online (Sandbox Code Playgroud)

不是创建test传入参数类型的临时对象的代码_b,而是使用默认构造函数作为名为_btype 的变量的变量声明test.因此,看起来像test使用第二个构造函数创建临时对象的代码片段是递归地创建类型的新对象test并再次调用构造函数.

要解决此问题,您可以为变量指定显式名称,例如

test t(_b);
Run Code Online (Sandbox Code Playgroud)

这只能解释为testnamed 的类型变量t,使用第二个构造函数初始化.

我以前从未见过这个,而且我已经用C++编程多年了.感谢您向我展示该语言的另一个角落案例!

官方解释:根据C++ 03 ISO规范,§6.8:

在涉及表达式语句和声明的语法中存在歧义:具有函数式显式类型转换(5.2.3)的表达式语句,因为其最左侧的子表达式与第一个声明符以(a)开头的声明无法区分.在这些情况下,该声明是一个声明.

(我强调).换句话说,任何时候C++都可以将语句解释为表达式(临时对象强制转换)或声明(变量),它将选择声明.C++规范明确给出了

T(一);

作为声明的一个例子,不是a某种类型的演员T.

这是C++的令人烦恼的解析 - 看起来像表达式而不是被解释为声明.我之前见过MVP,但在这种情况下我从未见过它.

希望这可以帮助!