Reputation: 639
I stumbled across this when trying to clean up a temporary variable. It seemed interesting enough to discuss.
ArrayType m_ArrayOfThings;
INT32 m_BitfieldOfThings;
...
// Assume MyType has a ctor overload with argument ArrayType and another with int32.
const MyType my_obj( m_ArrayOfThings.IsEmpty() ? m_BitfieldOfThings : m_ArrayOfThings )
Here is a simplified example of my set-up. Something similar may be found in UE4's FCollisionObjectQueryParams
constructors.
error C2446: no conversion from 'INT32' to 'ArrayType'
, since the type passed is unknown at compile-time.
auto temp = m_ArrayOfThings.IsEmpty() ? m_BitfieldOfThings : m_ArrayOfThings;
const MyType my_obj( temp );
This will also throw: error C3536: 'temp': cannot be used before it is initialized
.
It's obvious one should convert either variables to have matching types, so the type is known at compile-time, however, I was wondering if there exist semantics, tricks/hacks, or new features (c++17, etc.) to solve this as well.
Upvotes: 0
Views: 53
Reputation: 37495
You can just move constructor invocation to the right:
auto const my_obj{m_ArrayOfThings.IsEmpty() ? MyType{m_BitfieldOfThings} : MyType{m_ArrayOfThings}};
With C++17 this snippet will work even if MyType
is non-copyable / non-movable and will invoke only one constructor.
Upvotes: 2