C++23标准非限定名称查找示例在GCC 14.2.0中行为不符的原因
GCC 14.2.0与C++非限定名称查找标准示例的行为差异问题
C++标准的**非限定名称查找(unqualified name lookup)**章节中有示例1,代码如下:
struct T1 { struct U { int i; }; }; struct T2 { }; struct U1 {}; struct U2 {}; struct B { using T = T1; using U = U1; operator U1 T1::*(); operator U1 T2::*(); operator U2 T1::*(); operator U2 T2::*(); }; template<class X, class T> int g() { using U = U2; X().operator U T::*(); // #1, 优先在X的作用域中查找T X().operator U decltype(T())::*(); // #2 return 0; } int x = g<B, T2>(); // 标准预期:#1调用B::operator U1 T1::* // 标准预期:#2调用B::operator U1 T2::*
标准规定:转换类型标识(conversion-type-id)的类型说明符(type-specifier)或指针运算符(ptr-operator)中的非限定名称,应按其所在转换函数标识(conversion-function-id)的方式查找;未找到则进行非限定名称查找,仅考虑表示类型或特化为类型的模板的名称。
按标准规则分析:operator U T::*中的U和T应优先在类B的作用域中查找。当调用g<B, T2>()时,#1处应调用B::operator U1 T1::*(),#2处的decltype(T())实例化为T2,应调用B::operator U1 T2::*()。
添加以下实现代码后:
#include <iostream> B::operator U1 T1::*() { std::cout << __func__ << std::endl; return nullptr; } B::operator U1 T2::*() { std::cout << __func__ << std::endl; return nullptr; } B::operator U2 T1::*() { std::cout << __func__ << std::endl; return nullptr; } B::operator U2 T2::*() { std::cout << __func__ << std::endl; return nullptr; } int main() {}
使用GCC 14.2.0编译运行,结果为:
operator U2 T2::* operator U2 T2::*
该结果与标准预期不符,且未找到相关缺陷报告,特此询问原因。
内容的提问来源于stack exchange,提问作者BlowingWind
相关产品推荐
相关产品推荐

