Borian
Borian

Reputation: 622

inconsistent string sorting with template method

I am trying to do a template function that sorts 3 elements,
numbers(int, double) work fine but string's do not behave as expected

#include <cstdlib>
#include <algorithm>
#include <iostream>

using namespace std;

template<typename TYPE>
void sort3(TYPE n1, TYPE n2, TYPE n3) {
    TYPE arr[3];
    arr[0] = n1;
    arr[1] = n2;
    arr[2] = n3;
    sort(arr, arr + 3);

    for (int i = 0; i < 3; i++) {
        cout << arr[i] << " ";
    }
    cout << endl;
}

int main(int argc, char** argv) {
    sort3("B", "Z", "A");
    sort3(10.2, 99.0, 1.9);
    sort3(200, 50, 1);
    return 0;
}

gives me the following output:

A Z B

1.9 10.2 99

1 50 200

to my understanding sort3("B", "Z", "A"); should give me A B Z
it is not OS specific since it gives me the same result in online compiler
what is happening there ?

Upvotes: 1

Views: 141

Answers (3)

hr_117
hr_117

Reputation: 9627

IF you like to stay with calling sort3 with const char* you can add a "specialised" template:

template<>
void sort3(const char* n1, const char* n2,const char* n3) {
    sort3( string(n1), string(n2), string(n3));
}

With this sort3("B", "Z", "A"); also will work.

But your question "what is happening there ?" is already answered by Andy Prowl.

Upvotes: 1

Andy Prowl
Andy Prowl

Reputation: 126522

That's because what you are passing are string literals, which are arrays of characters. When passing them as arguments to a function, arrays decay to pointers. Therefore, what you are sorting is the value of those pointers (and not the strings they are pointing to).

Try this:

#include <string>

// ...

sort3(std::string("B"), std::string("Z"), std::string("A"));

This works because an overload of operator < for std::string exists, and std::sort uses operator < to compare elements when a custom comparator is not passed as a third argument (which is your case).

Upvotes: 4

Vaughn Cato
Vaughn Cato

Reputation: 64308

You end up comparing the pointers and not the actual string contents. One way to solve it would be like this:

sort3(std::string("B"), std::string("Z"), std::string("A"));

Upvotes: 3

Related Questions