【问题标题】:Clang fails to find const template member function from base classClang 无法从基类中找到 const 模板成员函数
【发布时间】:2018-08-20 11:12:20
【问题描述】:

以下 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++ 标准中的错误?

【问题讨论】:

  • 绝不是狼疮,也绝不是编译器错误。没有匹配 cd.f('x'); 'char::asdf` 不是一个东西。你想做什么?
  • @JiveDadson:肯定是其中之一的编译器错误 - 代码 sn-p 违反标准,它应该是错误(使用 GCC 成功编译的编译器错误)或代码 sn- p 很好,不应该出错(Clang 的编译器错误导致编译不成功)。
  • 代码不好。它不使用 Base,因为用户代码明确表示 Derived。
  • 今天我不合时宜...是的:你已经添加了using Base::f...对不起...忘记我说过的话。我不知道 SFINAE 禁用功能是否涵盖基类(如认为 liliscent )。再次抱歉。

标签: c++ c++11 gcc clang compiler-bug


【解决方案1】:

我认为这是一个 gcc 错误。

根据using-declarator(强调我的):

[namespace.udecl]

通过对 using-declarator 中的名称执行限定名称查找 ([basic.lookup.qual], [class.member.lookup]) 来找到 using-declarator 引入的声明集,不包括以下函数如下所述隐藏。

...

当 using-declarator 将基类中的声明引入派生类时,派生类中的成员函数和成员函数模板会覆盖和/或隐藏具有相同名称的成员函数和成员函数模板,参数-基类中的类型列表、cv 限定符和 ref 限定符(如果有)(而不是冲突)。此类隐藏或覆盖的声明被排除在 using-declarator 引入的声明集中。

在您的情况下,基类 f() 应该被隐藏,并且对派生类不可见。

另一个重要的一点是,using 的作用是在名称查找阶段,在 SFINAE 之前。因此,是否存在 SFINAE 没有影响。

【讨论】:

  • 很遗憾模板参数不是该列表的一部分:-/
猜你喜欢
  • 2016-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-31
  • 1970-01-01
  • 2012-09-12
  • 1970-01-01
  • 2023-04-02
相关资源
最近更新 更多