【问题标题】:C++ reference to overloaded function is ambiguousC++ 对重载函数的引用不明确
【发布时间】:2020-07-25 11:52:14
【问题描述】:

考虑以下 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 link

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

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

谢谢!

【问题讨论】:

  • 我认为实际错误隐藏在 func 名称查找后面。如果您手动将所有基类 func 名称带入 C(即 struct C : A, Utils&lt;C&gt; { using A::func; using Utils&lt;C&gt;::func; };),您将看到您在定义 C(又名 Self)时尝试解析 Self::func。使用A::func&lt;Count&gt;(...) 它可以工作,但这显然违背了编译器选择正确重载的想法。
  • 嗯,如果我改写struct C : A, Utils&lt;A&gt; {}(注意Self现在是A),即使此时定义了A,错误消息仍然相同。

标签: c++ templates inheritance overloading


【解决方案1】:

这里有两个问题。首先,您需要从两个基类中显式拉入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;
}

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

【讨论】:

  • 感谢您完成了这项工作!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-08
  • 2013-11-18
  • 2021-11-02
  • 1970-01-01
  • 2020-06-14
相关资源
最近更新 更多