I'm using a template function searchByCriteria<T>
where I would like to be able to run the function using both a string
and a double
. I have a list of custom-defined objects that have string
and double
attributes, and I would like to be able to use this function to check the criteria value (of whatever type, entered by the user), to check for matches in the object attributes of the same type.
I.e. User enters a double value, check the object collection for matching double values. User enters a string value, check the object collection for matching string values.
The problem I am having is once the value is entered, it is passed to another template function to be checked against the elements in the list. And at this point, the T
object that is passed as a parameter, needs to be converted to either a double or a string to allow checking for matches.
Here is the code for this part:
//get a sub-list of transactions
//of all that match specified search criteria
template <typename T>
const TransactionList TransactionList::getTransactionsForSearchCriteria(T criteria) const {
//make a copy of list to avoid deleting existing data
TransactionList copy(*this);
//to have appropriate transactions added in
//then returned as copy
TransactionList ret;
//////////////////////////////////////////
//before checking for matches can start///
//must ID datatype of T instance//////////
//////////////////////////////////////////
//check all transactions until list empty
while (copy.size() > 0)
{
//check that criteria matches transaction attribute
if (/*converted criteria matches corresponding attribute*/)
{
//flag as match
}
}
}
As you can see, the parameter value criteria
needs to be converted back into a specific data type before the while loop can be entered to check for matches. I am at a slight loss as to how to do this, as I am not aware of any casting methods in C++ that would be useful in this situation.
The only thing I can think of would be something like:
try
{
//example method
convertToDouble(criteria);
}
catch (SomeKindOfNumberException ex)
{
//cannot be a double
//so must be string
convertToString(criteria);
}
Any help is greatly appreciated.
Thanks, Mark
How about something like this?
FuncA can receive any T but it uses FuncB which is specialized for some specific types. If you want you can keep or delete FuncB(T) to support/avoid using unknown types.
The output of the previous code looks like:
Maybe you can add a
Criterion<T>
class holding user value and delegate the test to this class:Then your algorithm will look like this:
So your
T
object is a container, and you haven't given us a lot of information on it, but if you usevector
s internally to the object to contain the objects you'll be way ahead.Secondly if you were to use a
pair
to contain yourvector
s you could take advantage ofget
to select the correct member.So, for the purposes of writing an answer my
TransactionList
object will look like this:Then we can rewrite your function:
If you could ensure that the lists were maintained sorted, the standard provides binary search functionality which would dramatically improve your performance for large collections:
As far as determining if your inputted value is a
string
or adouble
when usingTransactionList result
, take all input as astring
then see if you can consume the entirestring
successfully into adouble
: Forcing String to int Function to Consume Entire StringLive Example