什么时候完整的类作用域在默认参数、默认成员初始值设定项和异常规范中真正有用



标准规定,默认参数、类成员默认初始值设定项和方法异常规范应在完整的类上下文中解析;也就是说,类在那些表达式或说明符中应该被视为完整的。自然地,类范围中定义的所有名称都应该对这些表达式可见,甚至是在表达式之后声明/定义的名称:

struct Test
{
// Well-formed, `bar` is looked up in complete-class context:
static void foo() noexcept(noexcept(bar()));
static void bar() noexcept;
};

我想,这一要求给编译器带来了很大的负担:他们别无选择,只能将这些表达式的解析推迟到类定义完成(或者在嵌套类的情况下,甚至更进一步(,这会导致其他问题和陷阱。

这就是为什么我忍不住想知道:为什么?它有什么好处
是否总是可以对成员声明进行重新排序,以便在使用名称之前总是声明名称(我指的是源文本流之前的(。

你能想出一个不能重新排序的例子吗?这样,一个默认参数、一个默认初始值设定项和一个异常规范显然必须在完整的类上下文中分析

反例:

struct Test
{
// Well-formed, `bar` is looked up in complete-class context:
static void foo() noexcept(noexcept(bar()));
static decltype(foo()) bar() noexcept;
};

这可能不是一个现实的例子(我可以明确地写void(,但不允许这种相互依赖将是一个不必要的主要限制,因为编译器可以处理如上所述的代码。

不同的例子可能更能解决你的问题:

struct Test
{
// Well-formed, `bar` is looked up in complete-class context:
static void foo() noexcept(noexcept(bar()));
static void bar(decltype(foo) f = foo) noexcept;
};

最新更新