模棱两可的重载函数仅因参数的模板参数而不同

时间:2019-03-18 23:33:16

标签: c++ c++11 overloading ambiguous-call

考虑以下代码:

SmartPointer<Data> Fix(SmartPointer<Data> data)
{
    return { /* Fixed Data */ };
}
SmartPointer<Data> Fix(SmartPointer<DataWrapper> dataWrapper)
{
    return Fix(dataWrapper->Data());    
}

我将如何重写它,以免引起“错误C2668:对重载函数的歧义调用”?

注意:我也希望能够传入一个子类,例如SmartPointer<SubclassOfDataWrapper>,并将其解析为超类的重载函数。

3 个答案:

答案 0 :(得分:1)

使用模板功能专门化。

template<typename T, class = void>
SmartPointer<Data> Fix(T data) { return {/* */}; }

template<typename T, enable_if_t< is_base_of_v<dataWrapper,T> || is_same_v<dataWrapper,T> >
SmartPointer<Data> Fix(SmartPointer<T> dataWrapper) { return {/* */};}

答案 1 :(得分:1)

检查您的智能指针类中是否有模板转换运算符。

更重要的是,如果转换无效,请检查是否有需要SFINAE排除的转换运算符。

转换运算符中的静态断言不会告诉编译器这些重载并不明确。

答案 2 :(得分:0)

由于Guillaume Racicot提供的提示,我提出了以下解决方案:

template<typename T>
SmartPointer<Data> Fix(SmartPointer<T> dataWrapper)
{
    // Note: only a subclass of DataWrapper would have the method ->Data()
    //            a subclass of Data would not have it (SFINAE principle)
    return Fix( dataWrapper->Data() );
}
template<>
SmartPointer<Data> Fix(SmartPointer<Data> data)
{
    return { /* Fixed Data */ };
}