本文介绍了SFINAE方法完全禁用clang中基类的模板方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

#include <iostream>
#include <utility>

struct B {
    template<typename T, std::enable_if_t<std::is_same<T, int>::value>* = nullptr>
    void foo(T) {
        std::cout<<"B::foo"<<std::endl;
    }
};

struct D: B {
    using B::foo;
    template<typename T, std::enable_if_t<std::is_same<T, std::string>::value>* = nullptr>
    void foo(T) {
        std::cout<<"D::foo"<<std::endl;
    }
};

int main() {
    D d;
    d.foo(2); // gcc: print "B::foo"; clang: compile error
    return 0;
}

假设我们要在派生类D中公开这两个foo()重载.gcc和Visual Studio编译并按我的预期打印"B :: foo".但是我收到了clang的编译错误:

Let's say we want to expose both foo() overloads in derived class D. gcc and Visual Studio compiles and print "B::foo" as I expected. But I get a compile error with clang:

prog.cc:22:7: error: no matching member function for call to 'foo'
    d.foo(2);
    ~~^~~
prog.cc:14:10: note: candidate template ignored: requirement 'std::is_same<int, std::string>::value' was not satisfied [with T = int]
    void foo(T) {

这是一个叮叮当当的错误吗?谢谢!

Is this a clang bug? Thanks!

推荐答案

我实际上认为这是gcc错误( 84832 密切相关,尽管正如Wakely指出的那样,这很可能是核心语言问题).

I actually think this is a gcc bug (84832 is closely related, though as Wakely notes it's possible that this should be a core language issue).

来自 [namespace.udecl]/15 :

[dcl/fct]/5 :

B::foo和D::foo具有相同的名称("foo"),参数类型列表([T]),cv限定符(无)和ref限定符(无).因此,派生的那个隐藏了基础的那个.

B::foo and D::foo have the same name ("foo"), parameter-type-list ([T]), cv-qualification (none), and ref-qualifier (none). Hence, the derived one hides the base one.

这篇关于SFINAE方法完全禁用clang中基类的模板方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-18 16:35