Support Forums

Full Version: [Code Snippet] Generic TryParse
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
This is a re-post of an article I originally posted on my website.

Please note that this is a code snippet, not a tutorial. It doesn't explain what the code does since I assume you are smart enough to work that out for yourself (it's pretty basic code tbh).

Introduction
Recently I've been doing some work templatifying my I/O classes, and from that have come to the conclusion that templates and streams make for the ultimate generic programming tool. One of the best changes the templates and streams has made is to my tryParse function (which works in a similar vein to the .NET TryParse functions).

Previously there were a load of these, each handling a different variable type using old C functions. Now the function has been replaced by a single templated function, and a std:Confusedtringstream.

If you try and tryParse a type a std:Confusedtringstream can't handle, it just doesn't compile; best of all is that you can still expand the function using template specialisation if you want to tryParse to your own custom types.

Code:
#ifndef TRYPARSE_H
#define TRYPARSE_H

#include <string>
#include <sstream>

//! Try and parse a string to another type
//! \return true if the conversion was ok, false otherwise
template <typename T>
bool tryParse(
        const std::string &str,  //!< String to convert
        T &out                        //!< Output variable
        )
{
        std::stringstream sstream;
        sstream.exceptions(std::ios::failbit | std::ios::badbit);
        sstream << str;
        try { sstream >> out; }
        catch(std::exception&) { return false; }
        return true;
}

#endif
And again, awsome!!!

It's a templated function, that part is the declaration of the template types. In the above code, T is used as an alias for the type for the variable "out".

An example of using this function would be:
Code:
std::string str = "10";
int val = 0;
if(tryParse(str, val))
{
    // val should now be 10
    assert(val == 10);
}

Because the template type is used as a parameter, the compiler is smart enough to work out that in the above example, T is of type int. If the template type is not used as a parameter, you would have to explicitly specify it (think STL containers).
Code:
// int is used as the template type of the list
std::list<int> myList;

Strictly speaking the two examples aren't equivalent since std::list is a class, and you always have to specify class template types. The general principal between a templated class and a templated function (or even a templated member function, or even a templated memeber function in a templated class) are all basically the same.

See templates.
Yeah I was researching a bit, and I also landed on the site.....
But any way thanks for clearing it up!