以下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 ++标准中的一个错误?
答案 0 :(得分:6)
我认为这是一个gcc bug。
根据using-declarator
(强调我的):
using-declarator引入的声明集是通过对using-declarator中的名称执行限定名查找([basic.lookup.qual],[class.member.lookup])来找到的,不包括函数隐藏如下所述。
...
当using-declarator将基类的声明带入派生类时,派生类中的成员函数和成员函数模板覆盖和/或隐藏成员函数和成员函数模板,其名称相同,参数 - 基类中的type-list,cv-qualification和ref-qualifier(如果有的话)(而不是冲突)。这些隐藏或重写的声明被排除在using-declarator引入的声明集之外。
在您的情况下,基类f()
应该被隐藏,并且对派生类是不可见的。
另一个重点是,using
的效果是在SFINAE之前的名称查找阶段。因此,是否存在SFINAE没有影响。