首页 > 解决方案 > C++ 对重载函数的引用不明确

问题描述

考虑以下 C++ 代码:

#include <vector>

struct A {
    template<int Count, typename InputIt, typename OutputIt>
    static OutputIt func(InputIt first, OutputIt result) {
        // write some stuff to result...
        return result;
    }
};

template<typename Self>
struct Utils {
    template<int Count, typename InputIt>
    static std::vector<int> func(InputIt first) {
        std::vector<int> vec;
        Self::func<Count>(first, std::back_inserter(vec));
        return vec;
    }
};

struct C : A, Utils<C> {};

auto example(const char* ptr) {
    return C::func<20>(ptr);
}

godbolt.org 链接

A实现了一些功能func()Utils一个辅助函数,简化了使用func()相同名称但一个参数 less(!) 的使用。C只是将这两者组合成一个结构。

现在,在里面example()我想调用func()定义在Utils. 但是,gcc 失败并显示错误“对 'func' 的引用不明确”(clang 也失败并显示类似的错误消息)。我希望编译器能够选择正确的func(),因为它们的参数数量不同。我在这里做错了什么?如何在不必重命名其中一个功能的情况下解决此问题?

谢谢!

标签: c++templatesinheritanceoverloading

解决方案


你这里有两个问题。首先,您需要func从两个基类中显式提取标识符(由于多重继承而必需):

struct C : A, Utils<C> {
    using A::func;
    using Utils<C>::func;
};

接下来,您需要一个template关键字 in Utils::func;

static std::vector<int> func(InputIt first) {
    std::vector<int> vec;
    Self::template func<Count>(first, std::back_inserter(vec));
    //    ^^^^^^^^
    return vec;
}

消除所需的模板实例化和另一个可能但奇怪的表达式之间的歧义(有关更多详细信息,请参见此处)。


推荐阅读