2013-07-29 18 views
6

Czy ktoś może dać mi znać najlepszy sposób, aby to osiągnąć.Sprawdź int lub listę <int>

Powiedz, mam funkcja szablon jak

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 

} 

Czy istnieje sposób, że mogę sprawdzić czy & ag jest pojedynczy obiekt lub listę obiektów. Również z danym interfejsem szablonu.

Nie ma znaczenia, czy odpowiedź wynika ze specyfikacji szablonu w jakiś sposób przez interfejs klasy. Jedyną rzeczą jest, że nie chcę określać typu obiektu ani typu listy.

Przykł. ag = int lub ag = lista

CB

+4

Czy specfically oznaczać listy lub dowolny stary pojemnik? – doctorlove

+0

Właściwie każdy pojemnik. Byłoby również dobrze, gdybym mógł odpowiednio wybrać typ zwrotu. Jeśli jeden obiekt zwraca pojedynczy obiekt, a argument jest typem powrotu kontenera kontenera. Z drugiej strony wewnątrz funkcji jest to ta sama rutyna dla obiektów innych niż iteracyjne, gdy jest to kontener. Byłoby lepiej, gdybym mógł mieć najkrótszy kod. –

+1

Konceptualnie, argumentacja do twojej funkcji jest kontenerem, a nie jest. Jeśli chcesz połączyć te dwie funkcje, brzmi to jak zły projekt. Czy masz zamiar traktować przekazanie pojedynczego elementu, tak samo jak kontener o rozmiarze 1? –

Odpowiedz

2

Można disambiguate z pewnymi cechami Typ:

#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 */) {} 
} 

Zobacz here
Ta cecha wyraźnie tylko wyciąga typów liczbowych, zamiast pojemnika . Typ powrotu zajmie trochę pracy. Są pomysły na wykrycie typu kontenerowego w odpowiedzi here i here

+0

thnx. to wydaje się być odpowiedź: –

+0

@cowboy Cieszę się, że mogę Ci pomóc. Jeśli Ci się spodoba, rozważ zaznaczenie tego linku http://stackoverflow.com/help/someone-answers – doctorlove

+0

Zrobiłem to. Czy ja nie? –

7

Hmm, może to wszystko, czego potrzebujesz to prosty przeciążenie?

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

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

Edit:

Czytając komentarze, mam wrażenie, że próbujesz overdesign swoją funkcję i dać go do wielu obowiązków.

Wydaje mi się, że najlepiej będzie z pierwszym przeciążeniem. Kiedykolwiek musisz zastosować funkcję do całego zakresu, użyj for_each.

+0

To może dobrze działać. Jednak chciałbym mieć coś takiego, ARGUMENT :: iterator itr = ag.begin() po sprawdzeniu, czy argument pochodzi z kontenera obiektu i stosuje tę samą procedurę, co w przypadku pojedynczych obiektów. Tak więc, jeśli mogę mieć to w jednej funkcji, będzie świetnie. –

+0

@cowboy: Można to osiągnąć, traktując kontener niebędący pojemnikiem jednym elementem. Ale to może być więcej pracy. – MSalters

1

Masz na myśli to?

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> 

Więc

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

get_result<int>(x); //Outputs: i 
+0

Thnx. Wolę rozwiązanie bez typowania. –

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. 
} 
+0

Ale to nie będzie błąd, jeśli zostaną podane dodatkowe argumenty? –

+0

@NeilKirk: W takim przypadku umieść go w "detalu przestrzeni nazw" (patrz odpowiedź doctorlove) – MSalters

+0

@MSalters Thnx. sprawdzi to. –

Powiązane problemy