1

I'm trying to convert a string to an enumerated type on Linux. I found this code on stackoverflow for doing this very thing, but am not sure I'm using function templates correctly. It compiles fine.

template <typename T>
typename boost::enable_if< boost::is_enum<T>, bool>::type
convert_string(const std::string& theString, T& theResult)
{
    typedef typename std::underlying_type<T>::type safe_type;

    std::istringstream iss(theString);
    safe_type temp; 
    const bool isValid = !(iss >> temp).fail();
    theResult = static_cast<T>(temp);

    return isValid;
} 

And here I'm trying to make proper use of it.

enum TestType {
    A1,
    B2,
    C3
};

string s = "A1";
TestType tt;

convert_string(s, tt);

The problem is that convert_string fails and tt is always 0 after the call. Also, the enum is located within an IDL for a middleware, but I'm testing with this.

Ender
  • 1,652
  • 2
  • 25
  • 50
  • Duplicate? Check this answer http://stackoverflow.com/questions/7163069/c-string-to-enum – Lee Brindley Apr 05 '15 at 18:38
  • As I said, found it here on SO ... http://stackoverflow.com/questions/1528374/how-can-i-extend-a-lexical-cast-to-support-enumerated-types , but can't get it to work, though seems it should, to me. – Ender Apr 05 '15 at 18:40
  • There is simply no way of doing this without using special compiler-specific extensions (and I don't think any major compiler have any such functionality) or use a mapping from the string to the enumeration value. – Some programmer dude Apr 05 '15 at 18:43
  • Could it be that in the example post they extended boost lexical cast? If so, I'm using boost. – Ender Apr 05 '15 at 18:51
  • also there is a `boost::enum` package that does that (using macros though) – Alexander Oh Apr 05 '15 at 20:33
  • possible duplicate of [Enum to string in C++11](http://stackoverflow.com/questions/21456262/enum-to-string-in-c11) – Alexander Oh Apr 05 '15 at 20:35

1 Answers1

3

You're not using the convert_string function correctly.

typedef typename std::underlying_type::type safe_type;

This is determining the storage type for the enum's value (e.g., int, long long, etc).

Then this type is used to convert theString to temp which is a numeric type. Therefore, the istringstream works by converting a string representing a numeric value (e.g., "0", "1", etc) to a numeric value.

Given this information you should understand why your code isn't working but the the following code does.

Code

enum TestType
{
    A1,
    B2,
    C3
};

template<typename T>
typename std::enable_if<std::is_enum<T>::value, bool>::type
convert_string(const std::string& theString, T& theResult)
{
    typedef typename std::underlying_type<T>::type safe_type;

    std::istringstream iss(theString);
    safe_type temp; 
    const bool isValid = !(iss >> temp).fail();
    theResult = static_cast<T>(temp);

    return isValid;
}

int main()
{
    std::string s = "0"; // This is the value of A1
    TestType tt;

    std::cout << std::boolalpha << convert_string(s, tt) << "\n";
    std::cout << std::boolalpha << (A1 == tt) << "\n";

    return 0;
}

Output

true
true

Solution

To support your usage you'll need to do something like others have suggested in the comments (e.g., mapping of string representation to enum)

Community
  • 1
  • 1
James Adkison
  • 9,412
  • 2
  • 29
  • 43
  • +1 for effort. I'd just have linked to the linked answer :) This is a shiny answer for the OP – sehe Apr 05 '15 at 23:24