Когда вы сначала включаете a1.h, он сразу же пытается включить a2.h, прежде чем объявить что-либо
a2.h ссылается на что-то в пространстве имен a1, которое еще не было объявлено
Когда вы сначала включаете a2.h, он сразу же пытается включить a1.h, прежде чем что-либо объявить
a1.h ссылается на что-то в пространстве имен a2, которое еще не было объявлено
Удаление typedef из a1.h, который вы не используете, и исключение a2.h удаляет цикл.
Или, как другим комментатором, форвард объявляет класс C.
// a1.h
#pragma once
//#include "a2.h"
namespace a1
{
const int x = 10;
// typedef a2::C B;
}