Chain function call only works if you don't save a reference to an intermediate type

59 views Asked by At

I'm using function calls like this to set up an instrument:

Setup().Thing().Channel(1,2).Channel(3,4).At("foo");

I'd like to be able to write a setup function which takes a list of pairs of channels, and applies them in a for-loop: for (...) setup.Channel(m,n). But if I assign the return value of Thing() or Channel() (the latter returns *this by reference), I get a runtime error: Unhandled exception thrown: read access violation. this-> was 0xFFFFFFFFFFFFFFC7.

auto& setup = Setup().Thing();
setup.Channel(1,2) // crashes here
     .Channel(3,4).At("foo");

auto& setup = Setup().Thing().Channel(1,2).Channel(3,4);
setup.At("foo"); // crashes here

The this in question, a.k.a. setup, comes from here:

function::SetupComponentFunction<SetupResult>& Thing(int index, std::string alias)
{
    auto type = std::make_shared<type::SetupType<T>>();
    auto function = std::make_shared<function::SetupComponentFunction<T>>(index, alias);

    setType(type);
    type->setFunction(function);

    return *(function.get());
};

Here are some of its members:

SetupComponentFunction<T>& Channel(int cha, int chb)
{
    memberFunction1(); // crashes when trying to step in here
    ...
    return *this;
}
std::shared_ptr<T> At(const std::string& alias)
{
    memberFunction2(alias); // able to step in here
    ...
}

// in base class:
#ifndef __INTELLISENSE__
    std::shared_ptr<attribute::AttributeItem> memberFunction1() override;
    std::shared_ptr<T> memberFunction2(const std::string& alias)
    {
        return memberVar(alias).get(); // crashes when trying to step in here
    }
#endif
boost::signals2::signal<std::shared_ptr<T>(const std::string&)> memberVar;

memberFunction1() and memberVar have no definitions that are visible to me. When you don't save auto& setup, they work fine but you can't 'step into' while debugging (it just steps over). When you do save auto& setup, you get the runtime error.

Is there anything here that suggests what the problem is? And is there a workaround? (A "chained function call builder"?!)

0

There are 0 answers