为什么在联机外定义的返回类型中不允许成员查找?

Why is member look-up not allowed in return types of out-of-line definitions?

提问人:Jan Schultke 提问时间:6/12/2023 最后编辑:Jan Schultke 更新时间:6/12/2023 访问量:101

问:

请考虑以下代码:

struct T {
    using iterator = int*;
    iterator begin() const;
    iterator end() const;
    /* ... */
};

// OK, member look-up allowed in trailing return types (since C++11)
auto T::begin() const -> iterator { /* ... */ }

// error: iterator does not name a type
iterator T::end() const { /* ... */ }

使第二种形式不可能的理由是什么?如果我们能引用返回类型中的成员名称,那显然会很有用。C++11 已经在一定程度上弥补了这一点,但是 C++98 或预标准的“带类的 C”呢?

我知道这需要某种形式的展望,因为解析器在解析之前无法理解。它不应该破坏与 C 的兼容性,因为 C 没有行外成员,因此我们可以以任何我们想要的方式实现它。iteratorT::end()

对于编译器来说,这是否太难实现 - 如果是这样,为什么 - 或者它只是一个设计决策?

++ 解析 编译 语言-律师 C++98

评论

1赞 NathanOliver 6/12/2023
如果该类型存在于该外部作用域中,会发生什么情况?那么应该使用哪个呢?iteratoriterator
0赞 Jan Schultke 6/12/2023
@NathanOliver-IsonStrike 与在尾随返回类型或其他允许非限定成员查找的上下文中使用时发生的情况相同:它会引用,因为它会隐藏 .我不确定这是否引入了解析歧义 if is a type,但事实并非如此。在命名空间范围内只允许声明,所以这可能没问题。iteratorT::iterator::iteratorT::iterator::iterator
0赞 Jeff Garrett 6/12/2023
通常,C++ 没有查找尚未引入的名称的名称查找。同样,您可以在尾随返回类型中使用参数名称,但不能在非尾随返回类型中使用参数名称。(完整的类上下文是一个例外。
0赞 user17732522 6/12/2023
我不确定它是否适用于这里,但是您不能真正延迟对 C++ 中的几乎任何内容进行名称查找,直到源代码的稍后时间点,因为解析几乎任何 C++ 都与上下文密切相关。例如,假定返回类型中的 a 是否会在下一次关闭之前引入嵌套的模板参数列表,这取决于对 之前的名称执行名称查找。根据结果,与返回类型匹配的令牌序列可能会有所不同。<><
1赞 user17732522 6/12/2023
@JanSchultke表达式可以显示为非类型模板参数,例如 可以是模板的完整模板 ID,也可以是部分模板 ID,其中第一个 template-id 没有结束语,具体取决于查找是否找到模板。对我来说,您始终可以区分返回类型的结束位置和声明者 id 的开始位置,而无需在返回类型中进行任何查找,这对我来说并不明显。A<B<C>A<>B

答: 暂无答案