How can I do the following but easier? I'm templating a class but I want it so that if typename T is of a literal type such as a string or char, then it can use the following member-function. If not then it cannot use it. I've been using typeid to tell whether one is a char or a string or a non-literal type. But it does not work since I cannot do it for both at the same time unless I overload the function. Is there any other way? I do not want to have to make a whole new templated class specialized for chars and strings, This is currently what I have:

template<typename T>
bool CustomType<T>::Contains(T LiteralType, bool CaseSensitive)
{
    if ((typeid(T).name() == typeid(std::string).name()) || (typeid(T).name() == typeid(char).name()))
    {
        std::vector<T> Temp = TypeData;         //Create  temporary type so the original doesn't change.
        if (!CaseSensitive)
        {
            if (typeid(T).name() == typeid(char).name())  //If it is a char..
                LiteralType = tolower(LiteralType);
            else
                for (size_t I = 0; I < LiteralType.length(); I++)
                    LiteralType[I] = tolower(LiteralType[I]);

            if (typeid(T).name() == typeid(char).name())  //If it is a char..
                for (size_t I = 0; I < Temp.size(); I++)
                    Temp[I] = tolower(Temp[I]);
            else
                for (size_t I = 0; I < Temp.size(); I++)
                    for (size_t J = 0; J < Temp[I].size(); J++)
                        Temp[I][J] = tolower(Temp[I][J]);
        }
        for (size_t I = 0; I < Temp.size(); I++)  //For both of them.
        {
            if (Temp[I] == LiteralType)
                return true;
        }
    }
    return false;
}

Recommended Answers

All 2 Replies

Here's an idea:

#include <iostream>
#include <string>

template <class A, class B> struct SameType { static const bool Result = false; };
template <class A> struct SameType <A, A>   { static const bool Result = true;  };

template <bool C, class True, class False> struct IfThenElse;
template <class True, class False> struct IfThenElse <true,  True, False> { typedef True  Result; };
template <class True, class False> struct IfThenElse <false, True, False> { typedef False Result; };

template <class T>
struct MyClass
{
    struct DoItStr  { void operator()() { std::cout << "std::string stuff..." << std::endl; } };
    struct DoItChar { void operator()() { std::cout << "char stuff..."        << std::endl; } };
    struct DontDoIt { void operator()(); /* using this will trigger a compilation error ;) */ };

    void doIt()
    {
        typedef typename IfThenElse <SameType<T, std::string>::Result, DoItStr,  DontDoIt>::Result DoIt_;
        typedef typename IfThenElse <SameType<T, char>::Result,        DoItChar, DoIt_   >::Result DoIt;

        DoIt()();
    }
};

int main()
{
    // MyClass<int>().doIt(); // uncomment to get an error
    MyClass<char>().doIt();
    // MyClass<double>().doIt(); // uncomment to get an error
    MyClass<std::string>().doIt();

    std::cin.get();
}

Ok, I think I'm done editing...

I would actually recommend using template specialization and the string::find() method instead:

template<>
bool CustomType<std::string>::Contains(const std::string& literal, bool CaseSensitive)
{
    std::string s(literal);

    if (!CaseSensitive)
    {
        for (size_t i; i < s.size(); i++)
        {
             s[i] = tolower(s[i]);
        }
    }

    return this->find(s);
} 

template<>
bool CustomType<char *>::Contains(const char* literal, bool CaseSensitive)
{
    std::string s(literal);
    std::string self(this);

    return self.Contains(s, CaseSensitive);
}

template<typename T>
bool CustomType<T>::Contains(T literal, bool CaseSensitive)
{
    throw("Not a literal type.");
}

Note that this works if you have a string for both the template type and the function argument, or a char pointer for both, but not when mixing the two. You would still need to overload the function to get that added functionality, if you want it:

template<>
bool CustomType<std::string>::Contains(const char* literal, bool CaseSensitive)
{
    std::string s(literal);

    return this->Contains(literal, CaseSensitive);
}

template<>
bool CustomType<char *>::Contains(const std::string& literal, bool CaseSensitive)
{
    std::string self(this);

    return self.Contains(literal, CaseSensitive);
}

I can't promise that this works, but AFAIK it should be more or less correct.

commented: Best Idea! I used this without the find because find can't be used on vectors. But Good! =] +5
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.