在编译时推导未知类型的函数重载

时间:2019-02-10 05:35:43

标签: c++ compiler-errors compile-time

在尝试清理临时变量时,我偶然发现了这一点。讨论起来似乎很有趣。

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 )

这是我的设置的简化示例。在UE4的FCollisionObjectQueryParams构造函数中可以找到类似的内容。


编译上面的内容将导致error C2446: no conversion from 'INT32' to 'ArrayType',因为在编译时传递的类型未知。

auto temp = m_ArrayOfThings.IsEmpty() ? m_BitfieldOfThings : m_ArrayOfThings;
const MyType my_obj( temp );

这还将抛出:error C3536: 'temp': cannot be used before it is initialized

很明显,应该将两个变量转换为具有匹配类型的变量,因此在编译时就知道该类型,但是,我想知道是否存在语义,技巧/黑客或新功能(c ++ 17等等)来解决这个问题。

1 个答案:

答案 0 :(得分:2)

您只需将构造函数调用移至右侧:

auto const my_obj{m_ArrayOfThings.IsEmpty() ? MyType{m_BitfieldOfThings} : MyType{m_ArrayOfThings}};

在C ++ 17中,即使MyType是不可复制/不可移动的,此代码段也将起作用,并且仅调用一个构造函数。