【发布时间】:2018-06-22 00:06:09
【问题描述】:
我希望两个类中的类型声明相互依赖。这是第一个使用 clang 和 gcc 编译的示例:
template <class Sum>
struct A
{
using X = char; // (1)
using Z = typename Sum::B::Y; // (2)
};
template <class Sum>
struct B
{
using Y = typename Sum::A::X;
};
struct AplusB
{
using A = ::A<AplusB>;
using B = ::B<AplusB>;
};
AplusB::A::Z z;
int main() {}
然而,有一个有趣的时刻。如果将第 (1) 行和 (2) 行互换,则编译失败并报错:
错误:“A”中没有名为“X”的类型
这让我怀疑原始代码在 C++ 标准的意义上是否真的有效,或者它恰好可以编译?
这是第二个例子,它也利用了模板实例化的顺序:
template <class Sum>
struct A
{
using X = char;
using P = typename Sum::B::Q;
};
template <class Sum>
struct B
{
using Y = typename Sum::A::X;
using Q = int;
};
struct AplusB
{
using A = ::A<AplusB>;
using B = ::B<AplusB>;
};
AplusB::A::X z; // (1)
AplusB::B::Q t; // (2)
int main() {}
这里如果你交换 (1) 和 (2) 它将无法编译并出现错误:
错误:“B”中没有名为“Q”的类型
所以问题是:标准是否允许类定义像这样相互依赖?
【问题讨论】:
-
AplusB在专业化A<AplusB>和B<AplusB>中不完整,使用它的成员应该是错误的 -
@PasserBy 如果我错了,请纠正我,但在
A<AplusB>的隐式实例化时AplusB已完成......(AplusB 中的别名声明不会隐式实例化 A 或B) -
@MassimilianoJanes 你可能是对的,我对此不太熟悉。
-
FWIW, VC++ 2017 15.6 Preview 编译第二个。 Micro$oft 一直在实现对两阶段查找的部分合规性,这可能与它有关。
-
这是CWG 287。
标签: c++ templates language-lawyer template-meta-programming