Search code examples
d

D - 'dup cannot deduce function' when used inside 'const' property


Consider the following code:

class Bar
{
}
class Foo
{
    private: 
        Bar[] bars_;
    public:
        Bar[] bars() const @property { return bars_.dup; }
}
void 
main()
{
    auto f = new Foo();
}

The intent is to have a read-only array of Bars. However this doesn't compile. Compilation fails with

template object.dup cannot deduce function

If const qualifier is removed, it compiles fine, but I really want to keep it - it does belong there. I've tried using bars_.dup!Bar instead, but that changes nothing. I'm clearly doing something wrong - DMD, LDC and GDC all display the same behaviour - but I can't figure out what.


Solution

  • You'd have to do some kind of deep copy there. With the const class, it means _bars is const too... which means the Bar is const as well. It is const all the way down.

    The dup function only does a shallow copy. It copies the array with fresh references to the objects inside, but does not duplicate the objects themselves too. So the dup, while a fresh, mutable array, still points to the same const objects so it won't let you cast it to Bar[], only const(Bar)[].

    The intent is to have a read-only array of Bars.

    Here's how I'd do it:

    const(Bar[]) bars() const @property { return bars_; }
    

    Just return the existing reference without duplicating it, but mark it const on the return value.

    The first const there with parens covers the return value, the next const covers the this reference. With both you should get what you want.