0

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();
    }
}

3 Answers 3

2

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();  
Sign up to request clarification or add additional context in comments.

Comments

1

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();
    }
}

Comments

0

Nope, but you could use next approach:

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

1 Comment

In that case, I still need the distinction. What I want is an "intelligent" for loop, that handles both containers

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.