2

The code is as follows:

template <class InputIterator, class OutputIterator>
inline OutputIterator copy(InputIterator first, InputIterator last,
                           OutputIterator result)
{
  return __copy_dispatch<InputIterator,OutputIterator>()(first, last, result);
}

//A overload version
inline char* copy(const char* first, const char* last, char* result) {
  memmove(result, first, last - first);
  return result + (last - first);
}

If I call copy(int*, int*), which is the best match, will the compiler instantiate a new function use int* as the template parameter, or int* will be convert to char*.

And what if I call copy(char[], char[]) notice I just use char[] to note the type of parameters.

Joey.Z
  • 4,492
  • 4
  • 38
  • 63
  • 1
    The template version since it matches the argumentlist better. Anyway, if two functions have the same signature the one with least templates parameters will be used. – Xale Jun 21 '13 at 07:13
  • 1
    If you call `copy(int*, int*)` there is no ambiguity: only the template can match. It is easy enough to check that. – juanchopanza Jun 21 '13 at 07:14
  • @Xale Is this a general rule that is also suitable for the partial specialization of a template. Because the partial specialization version is always the one that has less template parameters. – Joey.Z Jun 21 '13 at 07:28
  • 1
    Since no one seems to have mentioned it: `__` in a symbol name is undefined behavior (or at least it was in C++03). – James Kanze Jun 21 '13 at 09:15
  • 1
    @JamesKanze This is an excerpt of g++ implementation that only for internal use. And `copy` is the only client interface. :) – Joey.Z Jun 21 '13 at 10:24
  • 1
    @zoujyjs, Yes, If I understand your question correctly. – Xale Jun 22 '13 at 19:08

2 Answers2

4

Since int * is not implicitly convertible to char * nor to const char *, the template function will be called. Removing the template function would result in compile time error.

Suggestion: There is great value in playing around with the compiler yourself. You can add lines like

std::cout << "template function called.\n";

into your overloads or use the debugger to do that kind of stuff. It's a great learning experience. You might also simply read some C++ books for an introduction.

Ralph Tandetzky
  • 22,780
  • 11
  • 73
  • 120
  • Even if the `int*` is implicitly convertible to `char*`, the template version would be instantiated and then invoked. In case of template, the compiler looks for exact match which doesn't require any conversion (implicit or otherwise). – Nawaz Jun 21 '13 at 07:46
1

if I call copy(int*, int*), which is the best match,

There in only one match: the template. The version taking const char* does not match at all.

And what if I call copy(char[], char[])

again, the template wins, because the arguments are not const. If you did this:

const char* c1 = ....;
const char* c2 = ....;
copy(c1, c2);

then the non-template would win, because in the case of a perfect overload match, a non-template function takes precedence.

juanchopanza
  • 223,364
  • 34
  • 402
  • 480