Jergus Suja
Jergus Suja

Reputation: 21

Recursive noexcept specification inside class/struct

Follows up on the question Recursive noexcept specification. If I declare function f in scope of class or struct, it should be visible everywhere inside class/struct scope. Also in noexcept specifier (it should not matter if it is recursive call). MSVC v19.28 and Clang 12.0.1 accept this and compile this code, but GCC 11.2 does not? Why? Is it bug in GCC compiler or in MSVC and Clang?

struct S {

    template<typename T>
    static auto f(T && t) noexcept {
        return true;
    }

    template<typename T, typename... Ts>
    static auto f(T && t, Ts && ... ts) noexcept(noexcept(f(ts...))) {
        return f(ts...);
    }

};

int main() {
    S::f(true, 0, 5u);
}

GCC error message:

In instantiation of 'static auto S::f(T&&, Ts&& ...) [with T = bool; Ts 
= {int, unsigned int}]':
error: no matching function for call to 'S::f(int&, unsigned int&)'
    static auto f(T && t, Ts && ... ts) noexcept(noexcept(f(ts...))) {
                                                          ~^~~~~~~
note: candidate: 'template<class T> static auto S::f(T&&)'
    static auto f(T && t) noexcept {
                ^
note:   template argument deduction/substitution failed:
note:   candidate expects 1 argument, 2 provided
    static auto f(T && t, Ts && ... ts) noexcept(noexcept(f(ts...))) {
                                                          ~^~~~~~~

Upvotes: 0

Views: 124

Answers (1)

NutCracker
NutCracker

Reputation: 12273

I believe this is a GCC bug introduced in GCC 8. As you can see here, when compiled with GCC 7.5, everything compiles successfully.

Why should this compile successfully?

Because the noexcept-specifier of a specialization of a function template is instantiated only when needed.

Upvotes: 1

Related Questions