0

Good day,

I am writing a simple C++ Linked List using templates. I have got everything working, but I wanted to add to the functionality by making it case insensitive by converting all characters to lowercase for when the template is of type string.

So, I wrote the following snippet to handle any word and convert it to all lower cases:

        #define TEMPLATE string // changing this changes the template type in the rest of the program
        Stack <TEMPLATE> s; //not used in this example, but just to show that I have an actual template for a class declared at some point, not just a definition called TEMPLATE
        TEMPLATE word; // User inputs a word that is the same type of the Linked List Stack to compare if it is in the Stack.
        cin >> word; // just showing that user defines word
        for (unsigned int i = 0; i < word.length(); i++)
        {
            if (word.at(i) >= 'A' && word.at(i) <= 'Z')
                word.at(i) += 'a' - 'A';
        }

The problem is that when the TEMPLATE of my Stack, and subsequently the compared word to the stack is not of type string, then it obviously throws error messages because the for loop was written specifically to look at strings.

So, is there a way I could make this function more generic so that any type can be passed? (I don't think so, since there would be no error checking for ints, etc. String is the only one that relies on this)

Or, is there a way that I can only execute the above code when my Template for my Stack and compared variable is of type string?

I looked at exception handling, except I'm very much used to how Python works and so I could not figure out exactly how to implement in C++ instead.

Just as a side note, I am not using any built in functions to convert the string to all lower cases, so that is not an option either and I am not looking for recommendations of those.

Trever Wagenhals
  • 381
  • 5
  • 14
  • Macros are not how you do templates in C++. I mean, there's even a `template` keyword... The solution is template specialization, but then you'd need to use actual C++ templates and not macro hackery. – StoryTeller - Unslander Monica Apr 13 '17 at 07:42
  • I'm not sure if this snippet has you confused, or if I'm still doing something wrong. My Stack class is designed as a template. I could have just as easily written Stack s; and string word, but I wanted to make it so that both of these variable types changed together. If there is a proper way to do this, then if you could point me in the right direction I'd appreciate it. I haven't seen anything in regards to this elsewhere though, which is why I haven't done it. Thanks. – Trever Wagenhals Apr 13 '17 at 08:11
  • I'm not confused about anything. This isn't about your class template, it's about your hack of a function template. – StoryTeller - Unslander Monica Apr 13 '17 at 08:12
  • So, aside from independently declaring them as both type string, or int, or what say you, how could I appropriately do it all with the changing of a single line? Thanks again. – Trever Wagenhals Apr 13 '17 at 08:15
  • 1
    You have `using` instead of `#define` for your usage: `using MyType = std::string;`. – Jarod42 Apr 13 '17 at 08:19

1 Answers1

4

Create overloads to normalize your data:

std::string normalize(const std::string& s) {
    std::string res(s);
    for (auto& c : res) {
        c = std::tolower(c);
    }
    return res;
}

template <typename T>
const T& normalize(const T& t) { return t; }
Jarod42
  • 203,559
  • 14
  • 181
  • 302