c++ - 参数包递归扩展后`no matching function for call`

标签 c++ c++14 variadic-templates

请考虑以下程序:

#include <iostream>


template <int I, typename T, typename ...Args>
struct foo {
    static void bar(const T& t0, const T& t1, const Args&... args)
    {
        std::cout << "( " << t0 << ", " << t1 << " ) ";
        foo::bar(args...);
    }
};

template <int I, typename T>
struct foo<I, T> {
    static void bar(const T& t0, const T& t1)
    {
        std::cout << "( "<< t0 << ", " << t1 << " ) " << std::endl;
    }
};


int main() {
    foo<1, int, float>::bar(0, 1, 18.f, -7.f);
    return 0;
}

我希望它能够正常编译并在运行时输出以下(或左右)内容:

( 0, 1 ) ( 18, -7 )

但是,此代码通过 g++ -std=c++14 -pedantic -Wall -Wextra parampack.cpp (GCC 5.3.0) 生成以下输出:

parampack.cpp: In function ‘int main()’:
parampack.cpp:23:45: error: no matching function for call to ‘foo<1, int, float>::bar(int, int, float, float)’
     foo<1, int, float>::bar(0, 1, 18.f, -7.f);
                                             ^
parampack.cpp:6:17: note: candidate: static void foo<I, T, Args>::bar(const T&, const T&, const Args& ...) [with int I = 1; T = int; Args = {float}]
     static void bar(const T& t0, const T& t1, const Args&... args)
                 ^
parampack.cpp:6:17: note:   candidate expects 3 arguments, 4 provided
parampack.cpp: In instantiation of ‘static void foo<I, T, Args>::bar(const T&, const T&, const Args& ...) [with int I = 1; T = int; Args = {float}]’:
parampack.cpp:23:25:   required from here
parampack.cpp:9:17: error: no matching function for call to ‘foo<1, int, float>::bar(const float&)’
         foo::bar(args...);
                 ^
parampack.cpp:6:17: note: candidate: static void foo<I, T, Args>::bar(const T&, const T&, const Args& ...) [with int I = 1; T = int; Args = {float}]
     static void bar(const T& t0, const T& t1, const Args&... args)
                 ^
parampack.cpp:6:17: note:   candidate expects 3 arguments, 1 provided

我尝试了各种变体和排列,例如:

template <int I, typename T, typename U, typename ...Args>
struct foo {
    static void bar(const T& t0, const T& t1, const U& u0, const U& u1, const Args&... args)
    {
        std::cout << "( " << t0 << ", " << t1 << " ) ";
        foo::bar(u0, u1, args...);
    }
};

...但我似乎无法编译它并且我不太确定到底发生了什么

为什么编译器不知道要实例化哪些函数?

最佳答案

首先,您的参数数量错误 - 正如编译器所建议的那样。 foo<1, int float>::bar()有签名:

static void bar(int const&, int const&, float const& );

这是 3 个参数。您传递的是 4。因此出现了直截了当的错误。

您显然想做的是一次选择 2 个参数。在这种情况下,bar 中的尾随参数与 foo 中的尾随参数不同, 所以你想要:

template <int I, typename T, typename ...Args>
struct foo {
    template <class... Extra>
    static void bar(const T& t0, const T& t1, const Extra&... args)
    {
        std::cout << "( " << t0 << ", " << t1 << " ) ";
        foo::bar(args...); // <== (*)
    }
};

这会带来第二个问题:递归调用foo::bar() . foo有主模板的注入(inject)类名。这永远不会真正让你进入你的基本案例特化。所以,你想要:

foo<I, Args...>::bar(args...);

关于c++ - 参数包递归扩展后`no matching function for call`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39453545/

相关文章:

c++ - 将数据写入文件的 'best' 方法是什么,稍后再次读入。

c++ - 可以将算术表达式作为参数传递给函数来描述其中的逻辑吗?

使用 lambda 进行 C++ 模板参数推导

c++ - Qt3D QtQuick Scene2D 使用 C++

c++ - 将正数四舍五入到下一个最接近的 5 的倍数

c++ - 为什么 0 == ("abcde"+1) 不是常量表达式?

c++ - 如何继承纯虚函数C++的实现

c++ - 从函数类型中剥离所有限定符

c++ - Variadic 模板参数总是必须放在最后吗?

c++ - 可变参数模板 : unfold arguments in groups