The trick is to search, within the chains you want to check, a unique feature that allows you to distinguish between them without having to compare them 1 to 1.
In the simple example that you expose, with only 2 strings, you have 4 valid methods:
For the content of a certain position (in your example, the initial letter).
By the length.
Searching in an auxiliary list.
Calculating a signature of the string.
The first 2 are the easiest to implement; unfortunately, they require validity previously the string; that is, they do not check all the string, only certain properties. Method 1 would confuse between "hola"
e "hijo"
(both start with 'h'
). Method 2 would make the same mistake: both are 4 characters.
The 3 performs the check itself. Actually, it is a literal chaining . Check the chains 1 to 1, automatically. And it is prone to errors.
The 4 is much more generic, and gives rise to automate the process, through additional structures, such as std:map
. And avoid errors, by being able to attach additional information to the chains.
I give you an example of each method; may have some error (I have not checked), but illustrate the different methods exposed:
For the content of a certain position.
void redirect( const std::string &method_to_call ) {
switch( method_to_call[0] ) {
case 'a':
account( );
break;
case 's':
status( );
break;
default:
std::cout << "method not found!!" << std::endl;
}
}
By the length.
void redirect( const std::string &method_to_call ) {
switch( method_to_call.size( ) ) {
case 7:
account( );
break;
case 6:
status( );
break;
default:
std::cout << "method not found!!" << std::endl;
}
}
Searching a list.
::std::list< ::std::string > KeywordsList;
KeywordsList.push_front( "accout" );
KeywordsList.push_front( "status" );
...
void redirect( const std::string &method_to_call ) {
auto iter = find( KeywordsList.begin( ),
KeywordsList.end( ),
method_to_call );
switch( distance( iter, KeywordsList.end( ) ) {
case 0:
status( );
break;
case 1:
account( );
break;
default:
std::cout << "method not found!!" << std::endl;
}
}
Calculating a signature of the string.
std::size_t myhash( const ::std::string &s ) {
static ::std::hash< ::std::string > h{ };
return h( s );
}
...
const KStatus = myhash( "status" );
const KAccount = myhash( "account" );
...
void redirect( const std::string &method_to_call ) {
switch( myhash( method_to_call ) {
case KStatus:
status( );
break;
case KAccount:
account( );
break;
default:
std::cout << "method not found!!" << std::endl;
}
}
Bonus: ::std::unordered_map< >
.
This is the most powerful method of all. And one of the fastest.
void account( ) {
...
}
void status( ) {
...
}
::std::unordered_map< ::std::string, ::std::function< void( ) > > Keywords{
{ "account", account },
{ "status", status }
}
...
void redirect( const std::string &method_to_call ) {
auto iter = Keywords.find( method_to_call );
if( iter == Keywords.end( ) ) {
std::cout << "method not found!!" << std::endl;
} else {
iter->second( );
}
}