https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114695

--- Comment #3 from Vincent Piquet <vin.piquet at gmail dot com> ---
Interesting. Now I think the issue may actually be caused by pack expansion on
the call site. The issue also happens when Foo only has one base class, albeit
with a different error that at least has concise types on both sides.

==== test.cpp ====
template <typename X> struct Bar {
    void accept(X value) { }
};

template <typename...> struct Foo;

template <typename... Ts>
struct Foo<Bar<Ts>...> : Bar<Ts>... {
    template <typename T, template <typename> typename B = Bar>
    constexpr static B<T>* slice_by_type(B<T>* self) {
        return self;
    }

    template <typename... Us>
    void accept(Us... values) {
        (slice_by_type<Us>(this)->accept(values), ...);
    }
};

int main() {
    Foo<Bar<float>> foo;
    foo.accept(3.14f);
}
==== test.cpp ====

==== GCC 13.2 ====
test.cpp: In instantiation of 'void Foo<Bar<Ts>...>::accept(Us ...) [with Us =
{float}; Ts = {float}]':
test.cpp:22:15:   required from here
test.cpp:16:27: error: no matching function for call to 'Foo<Bar<float>
>::slice_by_type<float>(Foo<Bar<float> >*)'
   16 |         (slice_by_type<Us>(this)->accept(values), ...);
      |          ~~~~~~~~~~~~~~~~~^~~~~~
test.cpp:10:28: note: candidate: 'template<class T, template<class> class B>
static constexpr B<T>* Foo<Bar<Ts>...>::slice_by_type(B<T>*) [with B = T; Ts =
{float}]'
   10 |     constexpr static B<T>* slice_by_type(B<T>* self) {
      |                            ^~~~~~~~~~~~~
test.cpp:10:28: note:   template argument deduction/substitution failed:
test.cpp:16:27: note:   deduced conflicting types for parameter 'T' ('float'
and 'Bar<float>')
   16 |         (slice_by_type<Us>(this)->accept(values), ...);
      |          ~~~~~~~~~~~~~~~~~^~~~~~
==== GCC 13.2 ====

This may however be simplified so much that it becomes another bug. I'm unsure.

Reply via email to