GCC 将 `set` 成员函数与 `std::set` 混淆

imi*_*mix 8 c++ gcc compiler-bug

以下 C++ 代码给出了 GCC 错误(例如 13.1,请参阅godbolt.org),其中编译器似乎将set成员函数模板与混淆std::set

#include <set>
using namespace std;
template <typename T> struct C {
    template <int S> void set(T const &) { }
};
template <typename T> struct D : C<T> {
    void f(T const & v) { this->template set<0>(v); }
};
Run Code Online (Sandbox Code Playgroud)

它显然与该行有关,但我不明白当它由 显式限定时,using namespace std;编译器如何尝试set在全局或命名空间中查找。谁能启发我吗?stdthis->

use*_*522 3

这里有一个关于此的 GCC 错误报告。

根据评论,有一个关于该行为的相关 C++ 标准缺陷报告,但我找不到它。

一些背景信息:

当您有一个类似的类成员访问表达式X->Y(假设没有operator->重载)时,Y首先在 的类类型的上下文中进行查找X

但如果不成功,则Y也会在表达式的范围内进行查找。例如,这将查找std::set是否Yset并且您有一个using namespace std;范围内(template不影响查找)。因为您的基类是依赖的,所以在模板定义上下文的第一个查找阶段不会找到C<T>其成员。set

此查找规则允许您编写例如this->set<int>::size()当前类是否派生自set<int>.

现在的问题是,这应该如何与具有依赖基的当前类进行交互,这可能会导致set在实例化上下文中查找其成员。

我没有查过当前和以前的标准对此有何具体规定。