Var constructor for const ReferenceCountedObject* resolves to bool


#1

It’s simple to make this mistake if you’re a fan of making everything const that can be const!

For example:

static void testDynamicObject()
{
    Logger::writeToLog ("==== testDynamicObject ====");

    DynamicObject::Ptr object = new DynamicObject();
    object->setProperty ("thing", 100);
    
    var varObject (object.get());

    if (const auto* const tempObject = varObject.getDynamicObject())
    {
        Logger::writeToLog ("==== original =====");
        Logger::writeToLog (tempObject->getProperty ("thing"));
        
        var varObjectCopy (tempObject); // calls var (bool)
        
        Logger::writeToLog ("==== copy =========");
        Logger::writeToLog (varObjectCopy["thing"]);
        
        var varObjectAssign;
        varObjectAssign = tempObject; // calls operator= (bool)
        
        Logger::writeToLog ("==== copy =========");
        Logger::writeToLog (varObjectAssign["thing"]);
    }
    
    Logger::writeToLog ("====================");
}

This unexpectedly calls the constructor and assignment operator for the bool type, rather than the pointer types.

I thought one solution to this for DynamicObject specifically would be to add a costructor for const DynamicObject* then make a clone within the constructor. But DynamicObject::clone() is not marked const, so that won’t work.

Perhaps the easiest solution is to trigger a compile failure by deleting these constructors in the var class? As in:

...
    var (const ReferenceCountedObject* object) = delete;
    var& operator= (const ReferenceCountedObject* object) = delete;
};

#2

Ouch. Thanks Martin, I can’t see a nicer way of doing it so I’ll add the deleted constructor/operator.


#3

Doesn’t it make sense to have DynamicObject::clone() marked const? I would certainly be unpleasantly surprised if a->clone() modifies a.