Question

I am now studying the function template.

I tried following code.

template <typename TYPE>
TYPE& Max(TYPE& a, TYPE& b)
{
    return (a > b ? a : b);
}

template < >
char* Max<char*>(char* a, char* b)
{
    return (strcmp(a, b) > 0) ? a : b;
}

template < >
const char* Max<const char*>(const char* a, const char* b)
{
    return (strcmp(a, b) > 0) ? a : b;
}

void __fastcall TForm1::Button1Click(TObject *Sender)
{
    float a = 3.14;
    float b = 2.718;
    float c = Max(a, b);

    char *ca = "abc";
    char *cb = "def";
    char *cmp = Max(ca, cb);    // error (E2015)
}

On C++ Builder XE4, I received following error.

E2015 Ambiguity between 'char *Ma<>(char *, char *) at Unit1.cpp:43' 
and 'Max<>(char *,char *)at Unit1.cpp:43'

In this case, what should I do to avoid the Error 2015?

Was it helpful?

Solution

This code is rather nonstandard, and it indicates that your compiler is badly outdated.

First, those specializations aren't allowed. The primary template mentions references (TYPE &), so the explicit specializations also have to use the same types. They are allowed to change the function body of the original template, not the signature.

After that is fixed, it passes the IDEone online compiler with no more errors.

#include <string.h>

template <typename TYPE>
TYPE& Max(TYPE& a, TYPE& b)
{
    return (a > b ? a : b);
}

template < >
char*& Max<char*&>(char*& a, char*& b)
{
    return (strcmp(a, b) > 0) ? a : b;
}

template < >
const char*& Max<const char*>(const char*& a, const char*& b)
{
    return (strcmp(a, b) > 0) ? a : b;
}

int main()
{
    float a = 3.14;
    float b = 2.718;
    float c = Max(a, b);

    char *ca = "abc";
    char *cb = "def";
    char *cmp = Max(ca, cb);    // no error
}

http://ideone.com/gR9VFX

It might be a good idea to ask your instructor to upgrade, and point at discrepancies between your classroom compiler and IDEone (or another online compiler; they're always available and always free, just like their underlying software) for encouragement.

Besides compiler and correctness issues,

  1. The non-const char *& business is redundant. Since the function never modifies anything you can just implement it for const char and allow that to be used when the pointer isn't const. Perhaps both are needed because of how specialization works, but:

  2. Function specialization is almost always a bad idea. For example, you want const char * parameters here, not const char *&. Just remove the template <> line and the template arguments on the next line, and you will get an overload instead. This program is an exercise in extraneous templating, which just makes things hard for no reason.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top