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.

6
  • Duplicate? Check this answer stackoverflow.com/questions/7163069/c-string-to-enum Commented Apr 5, 2015 at 18:38
  • As I said, found it here on SO ... stackoverflow.com/questions/1528374/… , but can't get it to work, though seems it should, to me. Commented Apr 5, 2015 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. Commented Apr 5, 2015 at 18:43
  • Could it be that in the example post they extended boost lexical cast? If so, I'm using boost. Commented Apr 5, 2015 at 18:51
  • also there is a boost::enum package that does that (using macros though) Commented Apr 5, 2015 at 20:33

1 Answer 1

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)

Sign up to request clarification or add additional context in comments.

1 Comment

+1 for effort. I'd just have linked to the linked answer :) This is a shiny answer for the OP

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.