Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function template overloading difference [duplicate]

I get different behavior when trying to overload function and function template. For function:

void foo(int)
{
    std::cout << "int";
}

void foo(char)
{
    std::cout << "char";
}

foo(42) is int. But for function template:

template <int T>
void bar()
{
    std::cout << "int T";
}

template <char T>
void bar()
{
    std::cout << "char T";
}

bar<42>() is ambiguous call. This happens even if I use a char, like bar<'a'>(). Why does one work and not the other?

like image 438
user6378568 Avatar asked May 24 '16 23:05

user6378568


People also ask

What is the difference between function overloading and templates?

What is the difference between function overloading and templates? Both function overloading and templates are examples of polymorphism features of OOP. Function overloading is used when multiple functions do quite similar (not identical) operations, templates are used when multiple functions do identical operations.

What are the differences between function template and template function?

Function Template is the correct terminology (a template to instantiate functions from). Template Function is a colloquial synonym. So, there's no difference whatsoever.

Can a function template 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.

What is function overloading?

An overloaded function is really just a set of different functions that happen to have the same name. The determination of which function to use for a particular call is resolved at compile time. In Java, function overloading is also known as compile-time polymorphism and static polymorphism.


1 Answers

The standard N4140 (credit goes to M.M) gives this explanation and sample in 14.8.2 Template argument deduction:

9 Except as described above, the use of an invalid value shall not cause type deduction to fail. [Example: In the following example 1000 is converted to signed char and results in an implementation-defined value as specified in (4.7). In other words, both templates are considered even though 1000, when converted to signed char, results in an implementation-defined value.

template <int> int f(int);
template <signed char> int f(int);
int i1 = f<1>(0);    // ambiguous
int i2 = f<1000>(0); // ambiguous

end example ]

However, note that in following drafts the rules are changed because:

This is no longer correct, even ignoring the fact that some implementations may be able to represent the value 1000 as a signed char: integral and enumeration non-type template arguments are now converted constant expressions (14.3.2 [temp.arg.nontype] paragraph 1), and converted constant expressions disallow narrowing conversions (5.20 [expr.const] paragraph 3).

The proposed sample is:

template <int> int f(int);
template <signed char> int f(int);

int i1 = f<1000>(0); // OK
int i2 = f<1>(0);    // ambiguous; not narrowing
like image 92
AlexD Avatar answered Sep 28 '22 01:09

AlexD