首页 文章

c variadic模板:无法匹配功能

提问于
浏览
0

这是我的代码:

#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 ,我发现有很多类似的代码 . 所以我正在考虑使用可变参数模板来获得更好的设计 . (How to make a better design if two overload functions are similar

但是我不知道为什么会出错:

main.cpp:27:8:错误:没有匹配函数来调用'getChar'ch = getChar(1,std :: forward(str)...); main.cpp:37:2:注意:在实例化函数模板特化'func <>'这里请求func(generator); main.cpp:6:6:注意:候选函数不可行:没有已知的从'int'转换为'Generator&'的第一个参数char getChar(Generator&generator)main.cpp:11:6:注意:候选函数不是可行:需要2个参数,但是1提供了char getChar(int pos,const string&s)

那么,我可以有一些设计来避免使用 if...else...sizeof...(StringType) 一起工作吗?

1 回答

  • 1

    扩展模板时, entire 模板代码将完整地扩展和编译 .

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

    func(generator);
    

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

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

    您的编译错误变得非常明显: getchar(1);getChar() 的任何重载实例都不匹配 . if 语句总是评估为true,而 else 部分永远不会被执行的事实并不重要 . else 部分必须仍然是有效的C代码,它被编译,并且只有在编译之后它才会被优化掉(可能) . 它无法编译,因此编译错误 .

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

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

相关问题