这是我的代码:
#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 回答
扩展模板时, entire 模板代码将完整地扩展和编译 .
让我们看看这里发生了什么:
在生成的模板生成的函数中,
size
将为0,结果函数变为:您的编译错误变得非常明显:
getchar(1);
与getChar()
的任何重载实例都不匹配 .if
语句总是评估为true,而else
部分永远不会被执行的事实并不重要 .else
部分必须仍然是有效的C代码,它被编译,并且只有在编译之后它才会被优化掉(可能) . 它无法编译,因此编译错误 .现在回答你的问题“我不知道为什么会有错误” . 现在你知道了 . 如何解决这个问题成为一个不同的问题,答案是,根据具体情况,模板专业化和/或SFINAE的某种组合 .
看起来您的问题中的示例是一个缩写示例(因为模板函数永远不会工作,显然,如果参数包有两个或更多参数) . 这很好(并且100%符合显示最小,完整,可验证的示例的精神),但是提出所示代码的替代可编译版本可能无法回答您的真实问题 .