2015-11-13 3 views
0

У меня есть два контейнера:C++ 11 Диапазон основе для цикла: как использовать контейнер с объектами и указателями-объект

std::vector<ObjectClass> vecD; // container of objects 
std::vector< ObjectClass* > vecP; // container of pointers 

в моем коде, я хочу, чтобы цикл по всем элементам , Насколько я знаю, мне нужно, чтобы написать различные for петли, что означает

// container of objects 
for (const auto& elem : vecD) 
    elem.doStuff(); 


// container of pointers 
for (const auto& elem : vecP) 
    elem->doStuff();   // the "->" is needed instead of "." 

Есть ли способ сказать петлю «если elemets являются объекты, использовать их непосредственно. В противном случае, разыменования них первым»?

обновление Вот более сложный пример, чтобы уточнить:

У меня есть эти контейнеры. Они каждый используется в шаблонных функции:

template< typename ContainerT > 
void myfunc(const ContainerT& container) 
{ 
    for (const auto& elem : container) 
    { 
     if (elem_is_a_pointer) //how can this work? 
      elem->doStuff();  // member function 
     else 
      elem.doStuff(); 
    } 
} 

ответ

2

Вы можете написать маленькие помощник, которые выполняют разыменования, если необходимые

template<typename T> 
T& deref(T* p) { return *p; } 
template<typename T> 
T& deref(T& p) { return p; } 

затем код для петель эквивалентно

// container of objects 
for (const auto& elem : vecD) 
    deref(elem).doStuff(); 

// container of pointers 
for (const auto& elem : vecP) 
    deref(elem).doStuff(); 
0

Нет, но вы можете использовать следующий подход:

for (const auto* pElem : vecP) 
{ 
    const auto& elem = *pElem; 
    elem.doStuff(); 
} 
+0

В этом случае, я до сих пор нужно различие. То, что я хочу, - это «интеллектуальный» цикл, который обрабатывает оба контейнера –

1

Вы могли бы написать функцию, не являющийся членом, чтобы сделать отправку:

void doStuff (const ObjectClass& obj) { 
    obj.doStuff(); 
} 

void doStuff (const ObjectClass* obj) { 
    obj->doStuff(); 
} 

Затем вы можете написать обе петли таким же образом:

for (const auto& elem : vecD) 
    doStuff(elem); 

for (const auto& elem : vecP) 
    doStuff(elem); 

Для кода в вашем редактировании, вы можете написать простую вспомогательную функцию, чтобы сдирать указатели, а затем вызвать на что:

template <typename T> 
T& strip_pointers (T& obj) { 
    return obj; 
} 
template <typename T> 
T& strip_pointers (T* obj) { 
    return *obj; 
} 

template< typename ContainerT > 
void myfunc(const ContainerT& container) 
{ 
    for (const auto& elem : container) 
    { 
     strip_pointers(elem).doStuff(); 
    } 
} 
Смежные вопросы