Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

g++ fails to resolve template function overload

With the following code g++ fails:

template <typename X = int, typename T, typename ...R>
    inline void func(const T&, R...) {}

template <typename T>
    struct S {};

template <typename X = int, typename T, typename ...R>
    inline void func(const S<T>&, R...) {}

int main() {
    func(42);
    func(S<int>()); // OK
    func(S<int>(), 1); // NOK
    func<int>(S<int>(), 1); // NOK
}

with:

<source>: In function 'int main()':
<source>:13:21: error: call of overloaded 'func(S<int>, int)' is ambiguous
     func(S<int>(), 1); // NOK
                     ^
<source>:13:21: note: candidates are:
<source>:2:17: note: void func(const T&, R ...) [with X = int; T = S<int>; R = {int}]
     inline void func(const T&, R...) {}
                 ^
<source>:8:17: note: void func(const S<T>&, R ...) [with X = int; T = int; R = {int}]
     inline void func(const S<T>&, R...) {}
                 ^
<source>:14:26: error: call of overloaded 'func(S<int>, int)' is ambiguous
     func<int>(S<int>(), 1); // NOK
                          ^
...

Reproducible with gcc v4.8.1 and v9.1. Compiles with clang (v3.0.0 and v8.0.0), icc (v13.0.1 and v19.0.1), msvc (v19.14 and v19.20).
Is the code valid or is this a bug in gcc?

EDIT: Thanks everyone, your feedback was helpful for me. FYI, bug 90642 has been filed; looking forward for a definite answer.

like image 243
oknenavin Avatar asked May 25 '19 08:05

oknenavin


People also ask

Can template function be overloaded?

You may overload a function template either by a non-template function or by another function template. The function call f(1, 2) could match the argument types of both the template function and the non-template function.

How does overloading of template function occur?

The name of the function templates are the same but called with different arguments is known as function template overloading. If the function template is with the ordinary template, the name of the function remains the same but the number of parameters differs.

What is the difference between template and function overloading?

overloading is used when we have various functions , doing SIMILAR operations . template is used when we have various functions , doing IDENTICAL operations .

Does function template work with string?

The template function works for int and char, but not float and string.


1 Answers

Interesting question. I think what you run into here is overload resolution, more specifically partial ordering rules for template specialization

I quote:

Informally "A is more specialized than B" means "A accepts fewer types than B".

I think the clang is correct to compile that and the resulution should take the second candiate

template <typename X = int, typename T, typename ...R>
    inline void func(const S<T>& t, R... p) {}

Because in case the first argument is not of type S<T>, it is no longer viable and thus more specialized.

like image 62
maow Avatar answered Oct 20 '22 02:10

maow