3

I want to make a parse function that excludes the type string or char

template <typename T> bool parse(T & value, const string & token){ istringstream sin(token); T t; if( !(sin >>t) ) return false; char junk; if( sin >>junk ) return false; value = t; return true; } 

How can I do this?

3
  • Why? Why not just not call it as a string or char... much easier. Commented Oct 9, 2012 at 1:56
  • What do you want to happen for strings and chars? And what about char pointers and arrays? Commented Oct 9, 2012 at 2:03
  • I'm taking in an input that is supposed to have a sequence of numbers 1st which i store in an array. Then afterwards ideally there should be characters following the numbers. I need to parse the numbers into the proper type then store them into a template array i have somewhere else. Commented Oct 9, 2012 at 2:06

3 Answers 3

5

Depending on what you mean by exclude the types string or char. If you want it not to link you can declare but not define specializations for the types:

template <> void parse<std::string>( std::string & value, const std::string& token ); 

The compiler will see the specialization and not generate the code. The linker will fail as the symbol is not defined in any translation unit.

The second approach, a bit more complicated is not to fail at link time, but to make the compiler not accept the template for those types. This can be done with SFINAE, which is simpler in C++11, but if you need a C++03 solution you can google for it or add a comment:

template <typename T, typename = typename std::enable_if<!std::is_same<T,std::string> && !std::is_same<T,char>>::type > void parse( T & t, const std::string& token ) { // ... } 

(I have not run this through a compiler so the syntax might be a bit off, play with it) The compiler will see the template, and when it tries to perform the substitution of the type T it will fail due to the std::enable_if<...>::type not resolving to a type.

In general, what you probably want is to provide different overloads that perform a specific version of the parse and take precedence:

void parse( std::string& v, const std::string& token ) { v = token; } 

Note that this is not a template, but a regular function. A non-templated function will be a better match than a templated one when the arguments of the call are perfect matches.

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

2 Comments

Your suggestion works. I think I will go with overloaded functions though. It's an easier more readable solution.
This doesn't compile, it needs ::value after each std::is_same<T, [...]>.
0

You can use boost type traits. They have a type comparison check called is_same

http://www.boost.org/doc/libs/1_51_0/libs/type_traits/doc/html/boost_typetraits/reference/is_same.html

You can just use the result of the comparison to char and string.

Comments

0

template should be declared like this in David Rodríguez's method (for functions with return type):

template <template T, typename std::enable_if<!std::is_same<T,std::string>::value>::type* = nullptr > T func(T x){} 

For multiple condition:

template <template T, typename std::enable_if<!std::is_same<T,std::string>::value &&!std::is_same<T,int>::value>::type* = nullptr > T func(T x){} 

For functions without return type:

template <template T> typename std::enable_if<!std::is_same<T,std::string>::value>::type func(T x){} 

For multiple condition:

template <template T> typename std::enable_if<!std::is_same<T,std::string>::value &&!std::is_same<T,int>::value>::type func(T x){} 

Don't forget to include #include <type_traits>

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.