C++ Logo

std-discussion

Advanced search

Overloading a virtual function with a non-virtual function with a requires-clause

From: v.S. F. <de34_at_[hidden]>
Date: Wed, 3 Mar 2021 16:50:03 +0000
A virtual function cannot have a trailing requires-clause. However, while a virtual function is present in a class or class template, currently there is nothing prohibiting a non-virtual non-member function with the same parameter-type-list, the same cv-qualifiers (if any) and ref-qualifier (if any), and a trialing requires-clause to be declared in the same class or class template, because the two declarations do not correspond ([basic.scope.scope]/(3.3.1)<https://eel.is/c++draft/basic.scope.scope#3.3.1>).

So following code is currently well-formed, where both the virtual and the non-virtual overloads are odr-used:

template<int N>
struct Foo {
    virtual int bar() const { return N; }
    int bar() const requires (N > 0) { return 0; }
};

int main()
{
    Foo<42>{}.bar();
}

But such overloading cannot be properly supported on Itanium C++ ABI, where two Foo<42>::bar overloads share the same mangled name "_ZNK3FooILi42EE3barEv”. Clang 11 accepts it with option “-std=c++2a -O2” (https://gcc.godbolt.org/z/fP4YTf) but rejects it with option “-std=c++2a” (https://gcc.godbolt.org/z/rE8sjP).

On the other hand, such overloading can be supported by MSVC, because mangled names of virtual and non-virtual functions are always different on MS ABI.

I think this kind of overloading should be conditionally supported, and diagnostic should be required on platforms that cannot support it properly.

(I have mailed to wmm_at_[hidden]<mailto:wmm_at_[hidden]> twice for this issue but have not been replied yet.)

Jiang An

Received on 2021-03-03 10:50:14