Reputation: 6285
I am a bit shaky with C++ template syntax, so I'm not sure if what I'm envisioning is possible, and if it is, I'm unclear on correct syntax.
I would like to implement template functions like template<int> bool is( std::string& )
, template<double> bool is( std::string& )
, etc. so that I can call is <int> (...)
or is <double> (...)
instead of isInt(...)
or isDouble(...)
, etc. Is this possible? If so, how would you code the function signatures?
With my tenuous grasp of template syntax, my attempt was:
#include <iostream>
#include <cstdlib>
template<int>
bool is( std::string& raw )
{
if ( raw.empty() ) return false;
char* p;
int num = strtol( raw.c_str(), &p, 10);
return ( ( *p != '\0' ) ? false : true );
}
int main( int argc, char* argv[] )
{
std::string str("42");
std::cout << std::boolalpha << is <int> ( str ) << std::endl;
return 0;
}
This failed with the following errors:
>g++ -g main.cpp
main.cpp: In function ‘int main(int, char**)’:
main.cpp:16:51: error: no matching function for call to ‘is(std::string&)’
std::cout << std::boolalpha << is <int> ( str ) << std::endl;
^
main.cpp:5:6: note: candidate: template<int <anonymous> > bool is(std::string&)
bool is( std::string& raw )
^
main.cpp:5:6: note: template argument deduction/substitution failed:
Upvotes: 1
Views: 300
Reputation: 170153
My comment to your post withstanding, the way to do this easily is with a simple template that uses the std::istringstream
class to parse:
template<typename T>
bool is(std::string const& raw) {
std::istringstream parser(raw);
T t; parser >> t;
return !parser.fail() && parser.eof();
}
The obvious caveat is that T
must be default constructable. But on the plus side, the above will work for user defined types as well, so long as they implement operator >>
.
Upvotes: 6
Reputation: 1420
You need to use template specialisation for this:
#include <iostream>
#include <cstdlib>
template<class T> bool is(std::string& raw) = delete;
template<>
bool is<int>( std::string& raw )
{
if ( raw.empty() ) return false;
char* p;
int num = strtol( raw.c_str(), &p, 10);
return ( ( *p != '\0' ) ? false : true );
}
int main( int argc, char* argv[] )
{
std::string str("42");
std::cout << std::boolalpha << is <int> ( str ) << std::endl;
return 0;
}
You can read more about in here
Upvotes: 3