Home > Back-end >  c bubble sort routine with template functions doesn't work with string literals
c bubble sort routine with template functions doesn't work with string literals

Time:08-18

I have a bubble sort algorithm to order integers in a descending order. Next I am asked to implement a template specialization for type char* in which I replace the arithmetic operator between two integers (>) with (strcmp). The code seems to work, as I print out the number of successful swaps, but my output just shows the array of chars* in reverse order compared to what I have inputted. Any idea?

#include <iostream>
#include <cstring>
using namespace std;
const int n=10;

template <class T> void order (T&, T&);
template <class T> void sort(T[n]);
template <class T> void display(T[], int);

int main(){
    int arr[n]={12, 3, 7, 120, 69, 420, 15, 666, 23, 10};
    float _arr[n]={71.9,111.7,197.8,378.1,246.9,312.9,445.5,121,166.7,434.3};
    const char* str[n]={"have","you","put","them","aside","your",
    "crazy","thoughts","and","dreams"};
    sort(arr);
    display(arr, n);
    sort(_arr);
    display(_arr, n);
    sort(str);
    display(str, n);

    return 0;
}
template <class T> void order(T& a, T& b){
    T tmp;
    tmp=a;
    a=b;
    b=tmp;
    return;
}
template <> void order <char*>(char* &A, char* &B){
    char* tmp;
    tmp=A;
    A=B;
    B=tmp;
    return;
}
template <class T> void sort(T A[n]){
    int count=0;
    for (int i=0; i<n-1; i  ) {
        for (int j=0; j<n-1-i; j  ) {
            if (A[j 1]>A[j]){
                count  ;
                order(A[j], A[j 1]);
            } 
        }
    }
    cout <<"Swaps: " <<count <<endl;
} //doesn't work for strings because comparing pointers isn't sensible to chars
template <> void sort<char*>(char* A[n]){
    int count=0;
    for (int i=0; i<n-1; i  ) {
        for (int j=0; j<n-1-i; j  ) {
            if (strcmp(A[j 1],A[j])>0){
                count  ;
                order(A[j], A[j 1]);
            }
        }
    }
    cout <<"Swaps: " <<count <<endl;
}
template <class T> void display(T t[], int n){
    for (int k=0; k<n; k  ){
        cout <<t[k] <<endl;
    }
    cout <<endl;
    return;
}

Originally this was the template specialization for "sort":

template <> void sort<const char*>(const char* A[n])
...

but it would originate this error message:

error: specialization of ‘void sort(T*) [with T = const char*]’ after instantiation
   50 | template <> void sort<const char*>(const char* A[n]){

CodePudding user response:

You have const char *str[n], but your template specialisation takes char *, so as the compiler will not automatically cast away constness the compiler will select the default class T template.

You should also refactor the code so that for instance a baseSort() function takes a pointer to a comparison function so you don't need to repeat the for loops in both templates.

Note also that you don't need the order() specialisation as it is identical to the default one.

Finally, using namespace std; and defining sort() can cause all sorts of problems as the std::sort() is now in the same namespace.

Oh, and concerning your update, declaring templates but not defining them until after they are used is not a common pattern, and probably causes issues like the one you see for reasons I am not sure of...

  • Related