Reputation: 955
I have two containers:
std::vector< ObjectClass > vecD; // container of objects
std::vector< ObjectClass* > vecP; // container of pointers
in my code, I want to loop over all elements. As far as I know, I need to write distinct for
loops, that means
// 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 "."
Is there a way to tell the loop "if the elemets are objects, use them directly. Otherwise, dereference them first"?
update Here is a more elaborate example to clarify:
I have those containers. These are each used in a templated function:
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();
}
}
Upvotes: 0
Views: 95
Reputation: 65770
You could write a non-member function to do the dispatch:
void doStuff (const ObjectClass& obj) {
obj.doStuff();
}
void doStuff (const ObjectClass* obj) {
obj->doStuff();
}
Then you can write both loops in the same way:
for ( const auto& elem : vecD )
doStuff(elem);
for ( const auto& elem : vecP )
doStuff(elem);
For the code in your edit, you could write a simple helper function to strip off pointers, then call on that:
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();
}
}
Upvotes: 1
Reputation: 2241
You could write little helpers, which perform the dereferencing if neccessary
template<typename T>
T& deref(T* p) { return *p; }
template<typename T>
T& deref(T& p) { return p; }
then the code for the loops is equivalent
// container of objects
for ( const auto& elem : vecD )
deref(elem).doStuff();
// container of pointers
for ( const auto& elem : vecP )
deref(elem).doStuff();
Upvotes: 2
Reputation: 22710
Nope, but you could use next approach:
for ( const auto* pElem : vecP )
{
const auto& elem = *pElem;
elem.doStuff();
}
Upvotes: 0