【问题标题】:Ambiguous call on overloaded variadic template function对重载的可变参数模板函数的模糊调用
【发布时间】:2020-06-02 13:11:25
【问题描述】:

我从 github 下载了一个支持多维数组的 C++ 库,当我使用 GCC8.2.0 构建它时,编译器遇到了一条消息,说重载函数不明确。考虑以下代码:

// basic function, set the length i for the dimension D
template<int Rank,int D>
void set_array(std::array<int,Rank>& A,int i)
{
    A[D] = i;
}

// function with parameter pack, set the length for all dimensions recursively
template<int Rank,int D,typename... indices>
void set_array(std::array<int,Rank>& A,int i,indices... idx)
{
    A[D] = i;
    set_array<Rank,D+1>(A,idx...);
}

// class calls set_array in allocation
template<typename T,int Rank>
class MultiArray
{

private:
    std::array<int,Rank> _dim = {{0}};

    template<typename... indices>
    void allocate(indices... idx) {
        static_assert(sizeof...(idx) == Rank,
                      "NUMBER OF INDICES PASSED TO ALLOCATE DOES NOT MATCH RANK OF ARRAY");
        set_array<Rank,0>(_dim,idx...);
    }
};

// code to create object of above MultiArray class.

MultiArray<int, 1> a;
a.allocate(10)

编译器错误信息是: 调用重载的“set_array(std::array&, int&) 不明确,

我的理解是在调用set_array(_dim, 10)时,编译器不知道应该使用哪一个,因为参数包可以为空。我尝试了一些方法来修复但失败了。有什么解决方案可以帮助我吗?提前谢谢!

【问题讨论】:

  • 代码的哪一部分来自lib,哪一部分是你的?

标签: c++ templates ambiguous variadic


【解决方案1】:

您的问题是参数包允许为空。如果你确实有一个空包,那么

void set_array(std::array<int,Rank>& A,int i,indices... idx)

只是

void set_array(std::array<int,Rank>& A,int i)

与您的非可变模板匹配。您需要处理一个空参数包,最简单的方法是添加一个额外的参数,例如

template<int Rank,int D, typename First, typename... Rest>
void set_array(std::array<int,Rank>& A,int i,First first, Rest... rest)
{
    A[D] = i;
    set_array<Rank,D+1>(A,first, rest...);
}

现在,如果您只使用 2 个参数调用该函数,您将获得非可变参数重载,并且 3 个或更多参数将调用可变参数。

【讨论】:

    【解决方案2】:

    解决此问题的一种直接方法是,通过展开一次,至少需要一个参数用于第二次重载

    template<int Rank,int D,typename index0, typename... indices>
    

    【讨论】:

    • 谢谢 Dani,这与 Nathan Oliver 的解决方案相同。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多