Clang 无法从基类中找到 const 模板成员函数
Clang fails to find const template member function from base class
以下C++文件:
struct Base {
template <typename T, int = 42>
void f(T &&) const {}
};
struct Derived: Base {
template <typename T, typename X = typename T::asdf>
void f(T &&) const {}
using Base::f;
};
int main() {
Derived const cd;
cd.f('x');
}
使用GCC 编译良好,但不能使用 Clang:
$ g++-7.3.0 -std=c++11 test.cpp -o test -Wall -Wextra
$ g++-7.2.0 -std=c++11 test.cpp -o test -Wall -Wextra
$ g++-6.4.0 -std=c++11 test.cpp -o test -Wall -Wextra
$ g++-5.4.0 -std=c++11 test.cpp -o test -Wall -Wextra
$ g++-4.9.4 -std=c++11 test.cpp -o test -Wall -Wextra
$ clang++-4.0 -std=c++11 test.cpp -o test -Wall -Wextra
test.cpp:15:12: error: no matching member function for call to 'f'
cd.f('x');
~~~^
test.cpp:8:14: note: candidate template ignored: substitution failure [with T = char]: type 'char' cannot be used prior to '::' because it has no members
void f(T &&) const {}
^
1 error generated.
$ clang++-5.0 -std=c++11 test.cpp -o test -Wall -Wextra
test.cpp:15:12: error: no matching member function for call to 'f'
cd.f('x');
~~~^
test.cpp:8:14: note: candidate template ignored: substitution failure [with T = char]: type 'char' cannot be used prior to '::' because it has no members
void f(T &&) const {}
^
1 error generated.
$ clang++-6.0 -std=c++11 test.cpp -o test -Wall -Wextra
test.cpp:15:12: error: no matching member function for call to 'f'
cd.f('x');
~~~^
test.cpp:8:14: note: candidate template ignored: substitution failure [with T = char]: type 'char' cannot be used prior to '::' because it has no members
void f(T &&) const {}
^
1 error generated.
为什么它不使用 Clang 编译?我的代码正确吗?这是编译器错误吗?C++标准中的错误?
我认为这是一个 gcc 错误。
根据using-declarator
(强调我的):
[命名空间.udecl]
using-declarator引入的声明集是通过对 using-declarator 中的名称执行限定名称查找 ([basic.lookup.qual], [class.member.lookup]) 来查找的,不包括如下所述隐藏的函数。
。
当 using-declarator 将基类中的声明引入派生类时,派生类中的成员函数和成员函数模板将覆盖和/或隐藏基类中具有相同名称、参数类型列表、cv 限定符和 ref 限定符(如果有)的成员函数和成员函数模板(而不是冲突)。此类隐藏或重写的声明将从 using-声明符引入的声明集中排除。
在您的情况下,基类f()
应该是隐藏的,并且对派生类不可见。
另一个重要的一点是,using
的效果是在名称查找阶段,在SFINAE之前。因此,是否有SFINAE没有影响。
相关文章:
- 不允许运算符 const 参数调用 const 成员函数
- c++ 是否保证标头初始化的静态 const 成员跨编译单元和库共享单个实例?
- 在类声明中初始化 const 成员变量时在调试模式下出现异常
- 如何避免将 const 和非 const 成员函数输入到模板中的代码重复
- 初始化 const 成员的正确方法
- 使用 Boost 对具有 const 成员的类进行序列化
- 非常量调用 const 成员函数失败,只读位置C++
- PIMPL类的设置应该是const成员函数
- 与其他静态const成员初始化静态常量成员
- decltype 不会推断 const 对象的 const 成员
- 如何初始化不是静态的const成员
- 如何使用常量变量初始化类的 const 成员变量
- 使用模板参数初始化静态 const 成员
- 与const成员配对的向量
- 通过参考const成员通过参考时,尝试引用已删除的函数
- const成员初始化之前的用法是GCC和Clang的这种预期行为
- 通过const成员变量访问内联函数
- 与const成员一起安排新的和班级的分配
- 在const函数中调用非CONST成员的非const函数
- 为什么即使对于 "copy on write" 的 const 成员函数也返回一个代理类?