1

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 ?

1

3 Answers 3

4

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).

Sign up to request clarification or add additional context in comments.

4 Comments

can I create a generic comparator that I can pass "a" instead of string("a") ?
@Borian: Yes, you could do that. Just define a functor that has two call operators, one for const char* that would construct std::string from the operands and compare those objects, and another operator template that uses < for any type
@Andy Prowl: What do you think about a "specialised" (surly there is a more correct name for that) template function for const char *, calling the sort3 with strings?
@hr_117: You probably mean an overload of sort3 that accepts three const char* and calls the generic sort3 this way: sort3(std::string(arg1), std::string(arg2), std::string(arg3));. Yes, that is also a possibility :)
3

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"));

Comments

1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.