I'm having a peculiar issue. I thought I knew a decent amount of C++ but I must be overlooking some nuance?
I've got some templated classes, and essentially all that is happening is based on some condition, an object is being moved from one std::list to another.
The method of focus here is the doAndGet( T *t ). My intent is for t to come in as NULL (or whatever, I really don't care, but it should be NULL or nullptr, and if I end up moving a T element *t from myList to myOtherList, I want T *t to point to the item that was moved.
Now maybe there is something about std::list that I'm not aware of, but when stepping through my code, t gets assigned properly and—originally I thought after the method returned, but later found out that—right before the ret instruction, argument T *t gets set back to NULL
Can any guru shed some light on this issue? It's a real head-scratcher for me...
template<typename T, typename C>
class Base : IsDerivedFrom<T, C>
{
public:
    typedef std::list<T*> SpecialList;
    virtual bool doAndGet( T* t ) = 0;
protected:
    SpecialList myList;
};
template<typename T>
class Derived : public Base<T, Other>, public Other
{
public:
    Derived( void );
    virtual ~Derived( void );
    bool doAndGet( T* t );
protected:
    typename Base<T, Other>::SpecialList myOtherList;
};
template<typename T>
bool Derived<T>::doAndGet( T *t )
{
    // Nothing to process
    if (myOtherList.empty()) {return false;}
    t = (*myOtherList.begin());
    myOtherList.pop_front();
    if (true/* some condition needs to be moved */)
    {
        t->status = 1;
        this->myList.push_back(t);
        return true;
    } else
    {
        // Something bad happened...
        delete t;
        t = nullptr;
        return false;
    }
}
// Use... (pretend I defined MyOtherClass somewhere, not important)
Derived<MyOtherClass> derivedInstance;
MyOtherClass *t = nullptr;
if ( derivedInstance.doAndGet(t) )
{
    // ... Here I should expect `t` to be not `NULL` and not `nullptr`
    // This however, is not ever the case in my testing...
}
                If you want to pass in a variable to a function and have any changes within that function to be reflected back to the caller, you need to use a reference.
C++, like C, is pass by value, where a function only gets a copy of a variable. C++ has references to allow pass by reference.
In other words, your function signature should be:
bool doAndGet( T* &t );
to state that t is a reference to a T*, allowing changes to reflect back to the original pointer in the caller.
A simpler example follows:
#include <iostream>
static void change (int a, int &b) { a = b = 0; }
int main() {
    int a = 42, b = 42;
    change (a, b);
    std::cout << a << ' ' << b << '\n';
    return 0;
}
This outputs 42 0 because the a passed in is pass by value and changes are not reflected back to the caller. The b is passed in as a reference so changes are reflected back.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With