C++引用重载函数不明确

4

考虑以下 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() 的使用,具有相同的名称但比其少一个参数。 C 将这两个结合成一个结构体。

现在,在 example() 中,我想调用在 Utils 中定义的 func()。 但是,gcc 出错并显示“对 'func' 的引用不明确”(clang 也出错并显示类似的错误消息)。 我期望编译器能够选择正确的 func(),因为它们在参数数量上有所不同。 我在这里做错了什么? 如何修复此问题,而无需重命名其中一个函数?

谢谢!


我认为实际错误被隐藏在func名称查找背后。如果您手动将所有基类func名称引入C中(即struct C:A,Utils <C> {using A :: func; using Utils <C> :: func;};),则会发现您尝试在定义C(又名Self)时解决Self :: func。使用A :: func <Count>(...)可以解决问题,但这显然违背了编译器选择正确重载的想法。 - lubgr
嗯,如果我写成 struct C : A, Utils<A> {}(注意此时 Self 是 A),即使 A 在这个点已经被定义了,错误信息仍然是相同的。 - shilch
1个回答

3
你有两个问题。首先,你需要从两个基类中显式地引入func标识符(由于多重继承而必要):
struct C : A, Utils<C> {
    using A::func;
    using Utils<C>::func;
};

接下来,您需要在Utils::func中加入一个template关键字;
static std::vector<int> func(InputIt first) {
    std::vector<int> vec;
    Self::template func<Count>(first, std::back_inserter(vec));
    //    ^^^^^^^^
    return vec;
}

为了消除期望的模板实例化与其他可能的但奇怪的表达式之间的歧义(有关更多详细信息,请参见此处)。


谢谢,这解决了问题! - shilch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接