Search code examples
c++if-statementboostsuperclass

C++ calling superclass with if statment


I think I am missing something here but can't figure out what..

If I do this, I get compile error "error C2446: ':': no conversion from 'const boost::defer_lock_t' to 'const boost::try_to_lock_t'"

public: 
explicit BasicScopedLock( CCondition& condition, bool initiallyLocked = true ) 
    : LockType( condition.mutex, (initiallyLocked == true ? (boost::try_to_lock) : (boost::defer_lock)) ) 
    , m_condition( condition ) 
{ 
} 

But if I do this, it compiles.

public: 
explicit BasicScopedLock( CCondition& condition, bool initiallyLocked = true ) 
    : LockType( condition.mutex, boost::try_to_lock ) 
    , m_condition( condition ) 
{ 
} 

This works too...

public: 
explicit BasicScopedLock( CCondition& condition, bool initiallyLocked = true ) 
    : LockType( condition.mutex, boost::defer_lock ) 
    , m_condition( condition ) 
{ 
} 

Does anyone have a clue on why compiler doesn't like the if statement here?

Thank you!


Solution

  • The problem is that boost::try_to_lock and boost::defer_lock are of completely unrelated types, and LockType( condition.mutex, boost::try_to_lock) and LockType(condition.mutex, boost::defer_lock) are invoking separate overloads. As such, you can't use the ternary operator to pick between them.

    Your options are:

    A. to find another overload of the LockType constructor that will allow you to switch at runtime (this is obviously best)

    B. if LockType is a moveable type, then you can write a function:

    CLockType create_lock_type( CMutex& mutex, bool initiallyLocked)
    {
        if (initiallyLocked)
            return CLockType(mutex,boost::try_to_lock);
        else
            return CLockType(mutex,boost::defer_lock);
    }
    

    C. to use the universal solution to problems in computer science: add another level of indirection. Change the declaration of LockType to:

        std::unique_ptr<CLockType> pLockType;
    

    and the initialization to:

      : pLockType(initiallyLocked? 
             std::make_unique<CLockType>(condition.mutex, boost::try_to_lock):
             std::make_unqiue<CLockType>(condition.mutex, boost::defer_lock))