当前位置: 首页 > 知识库问答 >
问题:

C可变参数模板:无法匹配函数

阳英朗
2023-03-14

以下是我的代码:< br >

#include <iostream>
#include "Generator.h" // user-defined class

char getChar(Generator & generator)
{
    return generator.generateChar();
}

char getChar(int pos, const string & s)
{
    return s[pos];
}

template<typename... StringType>
void func(Generator & generator, StringType &&... str)
{
    char ch;
    int size = sizeof...(StringType);
    // lots of things to do
    if (size == 0)
    {
        ch = getChar(generator);
    }
    else
    {
        ch = getChar(1, std::forward<StringType>(str)...); // ERROR here
    }
}

int main(int argc, char ** argv)
{
    Generator generator;

    func(generator);
    func(generator, "abc");

    return 0;
}

一开始我只是重载了函数func,发现有很多类似的代码。所以我正在考虑使用可变参数模板来获得更好的设计。(如果两个重载函数相似,如何做出更好的设计)

但是我不知道为什么会有错误:< br >

main.cpp:27: 8:错误:没有匹配函数调用'getChar'ch=getChar(1, std::forward(str)...);

主要的cpp:37:2:注意:在函数模板专门化'func'的实例化中

main.cpp:6:6:注意:候选函数不可行:没有从“int”到“Generator”的已知转换

main.cpp:11:6:注意:候选函数不可行:需要2个参数,但提供了1个char getChar(int pos,const string



顺便问一句,我可以做一些设计来避免使用<code>if…else…?

共有1个答案

惠诚
2023-03-14

当模板展开时,整个模板代码将完整地展开和编译。

让我们看看这里发生了什么:

func(generator);

在生成的模板生成的函数中,size 将为 0,生成的函数变为:

if (0 == 0)
{
    ch = getChar(generator);
}
else
{
    ch = getChar(1);
}

编译错误变得非常明显:getchar(1)getChar()的任何重载实例都不匹配。if语句将始终求值为true,而else部分将永远不会执行这一事实并不重要。else部分必须仍然是有效的C代码,可以编译,并且只有在编译之后才能优化(可能)。并且它不能被编译,因此编译错误。

现在这回答了你的问题“我不知道为什么会有错误”。现在你知道了。如何解决这个问题是一个不同的问题,根据具体情况,答案是模板专门化和/或SFINAE的某种组合。

看起来问题中的示例是一个缩写示例(因为很明显,如果参数包具有两个或多个参数,则模板函数将永远不会起作用)。这很好(并且100%符合显示最小,完整,可验证的示例的精神),但是提出所示代码的替代可编译版本可能不会回答您的真正问题。

 类似资料:
  • 在C++11之前,类模板和函数模板只能含有固定数量的模板参数。C++11增强了模板功能,允许模板定义中包含0到任意个模板参数,这就是可变参数模板。可变参数模板的加入使得C++11的功能变得更加强大,而由此也带来了许多神奇的用法。 可变参数模板 可变参数模板和普通模板的语义是一样的,只是写法上稍有区别,声明可变参数模板时需要在typename或class后面带上省略号...: template<ty

  • 受这个答案的启发,我生成了这段代码,其输出取决于编译器: 如果使用 GCC 11 编译,调用

  • 请考虑以下定义和演绎指南: 如果我尝试使用显式模板参数实例化 ,代码将正确编译: 如果我试图通过演绎指南实例化< code>foo... > G7产生编译器错误: clang 5 爆炸: wandbox上的实例 虽然clang肯定被窃听了(报告为问题#32673),但g拒绝我的代码是正确的吗?我的代码格式错误吗?

  • 我已经编写了一个具有递归评估的可变参数模板函数。对于最后一个参数,我在没有可变参数包的情况下实现了专业化,并且一切正常。 现在我想把可变函数参数转换成模板参数。 这是我的尝试: gcc和clang报告了一个模糊的过载,并且无法使用空参数包在“专业化”和“可变参数”之间做出决定。 我尝试删除特化并检查可变参数模板中的包大小,但是如果没有特化,编译器就无法推断出参数“p”。

  • std=C14的g在函子类的模板方法(本身不是模板)上给我一个“无法推断模板参数'Key'”错误。我不知道为什么。代码看起来应该可以工作。 我正在实现一个2-3树,它有一个采用函子的层次顺序遍历方法。操作人员tree23代码基本上是这样的: 级别顺序遍历调用仿函数的函数调用操作符,向其传递两个参数。 函子非常简单:

  • 我努力一步一步地编写示例,使其清晰易懂。 此处显示的object BaseCreator公开了一个create函数,该函数使用一个内部类NewObject来分配一个t类型的新对象。new object类的默认方法是使用new运算符的常用方法,但是可以使用专门化来更改它,以使用不同的进程。我们稍后会看到它。 这很好,例如,假设我们有以下对象类型: 我们可以很容易地创建它们,例如: 我们还可以为特定对