6

Can anybody please let me know the best way to accomplish this.

Say, I have a template function like

template<typename ARGUMENT>
void get_result(ARGUMENT &ag)
{

// arg can be a single object of a particular object or list of objects of that particular class. 
//rest

}

Is there a way that I can check if the &ag is a single object or list of objects. Also, with the given template interface.

It does not matter if the answer is by template specification in some way by a class interface. Only thing is I do not want to specify the object type or list type.

Ex. ag = int or ag = list

CB

billz
  • 44,644
  • 9
  • 83
  • 100
cow boy
  • 85
  • 7
  • 4
    Do you specfically mean list, or any old container? – doctorlove Jul 29 '13 at 09:16
  • Actually any container. Also it would be good if I can select the return type accordingly. If one object single object return and if argument is a container container return type. On the other hand inside the function it is the same routine for objects other than iterating when it is a container. It would be better if I can have the shortest code. – cow boy Jul 29 '13 at 09:48
  • 1
    Conceptually, either the arguement to your function is a container or it's not. If you want to mix the two within the same function, it sounds like bad design. Is your intention to treat passing a single element, as effectively a container of size 1? – Neil Kirk Jul 29 '13 at 11:05
  • @NeilKirk Why is it a bad design. This is just to provide the user with the same interface to give arguements as a single object (say geometric point) and a set of objects (set of points). – cow boy Jul 29 '13 at 11:22
  • Provide two functions, one that takes a single object and one that takes a group. – Neil Kirk Jul 29 '13 at 11:29
  • The library is template and I have to respect the design and can not provide two functions. – cow boy Jul 29 '13 at 11:40

4 Answers4

7

Hmm, maybe all you need is simple overloading?

template<typename ARGUMENT>
void get_result(ARGUMENT& ag);

template<typename ARGUMENT>
void get_result(std::list<ARGUMENT>& ag);

Edit:

Reading your comments, I have a feeling you're trying to overdesign your function and give it to many responsibilities.

I think you'd be best off with the first overload only. Whenever you need to apply the function to a whole range, use for_each.

jrok
  • 54,456
  • 9
  • 109
  • 141
  • This might well work. However I would like to to have something like, ARGUMENT::iterator itr = ag.begin() after checking if the argument is from a object container and apply the same routine as for single objects. So, if I can have it in one function that will be great. – cow boy Jul 29 '13 at 10:07
  • @cowboy: You can achieve that by treating a non-container as a container with one element. But that might actually be more work. – MSalters Jul 29 '13 at 10:55
2

You could disambiguate with some type traits:

#include <type_traits>

template<typename T>
T get_result(T arg) 
{ 
    return detail::get_result(arg, typename std::is_arithmetic<T>::type() ); 
}

namespace detail {
    template<typename T>
    T get_result(T arg, std::false_type /* dummy */) { }

    template<typename T>
    T get_result(T arg, std::true_type /* dummy */) {}
}

See here
This trait clearly just pulls out the numeric types, rather than a container. The return type will take some work. There are ideas for detecting a container type in the answers here and here

Community
  • 1
  • 1
doctorlove
  • 18,872
  • 2
  • 46
  • 62
1

Do you mean this ?

template<typename ARGUMENT>
void get_result(ARGUMENT &ag)
{
   std::cout<<typeid(ARGUMENT).name();  //Check the value 

/*This returns a name of the type in question.
 It may satisfy your criteria.*/
}
//Header :#include <typeinfo> 

So,

int x=12;
list <int> l;
get_result<list<int>>(l); // Outputs: St4listIiSaIiEE

get_result<int>(x); //Outputs: i
P0W
  • 46,614
  • 9
  • 72
  • 119
1

SFINAE:

template<typename T>
T get_result(T arg, typename T::value_type* = 0) 
{ 
    // Container.
}

template<typename T>
T get_result(T arg, ...) 
{ 
    // Not a container. Vararg overloads rank lower in overload resolution.
}
MSalters
  • 173,980
  • 10
  • 155
  • 350