1
votes

I have a function that aims to convert a string from a config file in to various different types. A special case has needed to be inserted to handle bool's as "false" equates to true when using a string stream.

Separate functions are not really an option as it would involve type checking for every type we are using.

The function worked correctly when part of a class previously, however to make it more usable it was moved in to its own start function. The function throws 2 errors on the return true's. The return false's are as expected.

Below is the code example and the errors thrown by visual studio.

template <typename T>
static T StringCast(string inValue)
{
    if(typeid(T) == typeid(bool))
    {
        if(inValue == "true")
            return true;
        if(inValue == "false")
            return false;
        if(inValue == "1")
            return true;
        if(inValue == "0")
            return false;
        return false;
    }

    std::istringstream stream(inValue);
    T t;
    stream >> t;
    return t;
}

Error 1 error C2664: 'std::basic_string<_Elem,_Traits,_Ax>::basic_string(const std::basic_string<_Elem,_Traits,_Ax> &)' : cannot convert parameter 1 from 'bool' to 'const std::basic_string<_Elem,_Traits,_Ax> &'

Error 2 error C2664: 'std::basic_string<_Elem,_Traits,_Ax>::basic_string(const std::basic_string<_Elem,_Traits,_Ax> &)' : cannot convert parameter 1 from 'bool' to 'const std::basic_string<_Elem,_Traits,_Ax> &'

1
ideone.com/1ZqKf compiles fine.Luchian Grigore
Calling it bool b = StringCast<bool>("true"); works fine under VS2010marcinj
@luskan don't mislead OP: ideone.com/0AKMJPiotrNycz
It's used from within another template function. template <typename T> T INIParser::GetValue(string key) { return StringCast<T>(this->iniData[key]); }Ian Cant
@LuchianGrigore don't mislead OP ideone.com/0AKMJPiotrNycz

1 Answers

2
votes

If you want to have specialization for bool - then just define specialization for bool. Your way is not possible. Use the proper way below:

template <typename T>
T StringCast(string inValue)
{
    std::istringstream stream(inValue);
    T t;
    stream >> t;
    return t;
}

template <>
bool StringCast<bool>(string inValue)
{
        if(inValue == "true")
            return true;
        if(inValue == "false")
            return false;
        if(inValue == "1")
            return true;
        if(inValue == "0")
            return false;
        return false;
}

int main() {
   int a = StringCast<int>("112");
   bool b = StringCast<bool>("true"); 
}