我无法弄清楚如何解决我遇到的编译器错误。我把它简化为这个最简单的表示法:
enum EAtomId { EAtomId_Test };
int StringFormat(char* o_dest, size_t i_destSizeChars, const char* i_format, ...);
template <size_t SIZE>
int StringFormat(char (&o_dest)[SIZE], EAtomId i_format, ...);
void func()
{
char textBuffer[1000];
StringFormat(textBuffer, EAtomId_Test, "hi there");
}
编译错误是:
repro.cpp(17) : error C2666: 'StringFormat' : 2 overloads have similar conversions
C:\Users\sbilas\Desktop\repro.cpp(9): could be 'int StringFormat(char *,size_t,const char *,...)'
while trying to match the argument list '(char [1000], EAtomId, const char [9])'
这是完整的错误btw。我有点惊讶它没有列出两个可用的版本..
我遇到这个错误的几个问题。首先,我不明白为什么它含糊不清。编译器不应该看到char(&amp;)[]版本作为匹配的明显案例吗?第二,如何在进行查找时阻止枚举转换为size_t?好像我在这里遇到了一些非常具体的C ++规则。
对我来说最简单的解决方法是将缓冲区大小的size_t放在实际缓冲区的前面。但是这将破坏我们在代码中放入缓冲区然后大小的所有约定。还有另一种方法吗?
这是在VC ++ 2005 btw上,但它在我拥有的其他几个编译器上重现(这是在跨平台游戏中)。
答案 0 :(得分:2)
您有StringFormat
的两个声明:
int StringFormat(char* o_dest, size_t i_destSizeChars,
const char* i_format, ...);
template <size_t SIZE>
int StringFormat(char (&o_dest)[SIZE], EAtomId i_format, ...);
当函数模板和普通(非模板)函数都可用时,阅读与参数相关的查找和替换规则。
答案 1 :(得分:2)
上述代码的问题是由普通的重载解析规则引起的,并不是特定于模板的。以下带有两个普通函数的代码仍然显示出歧义:
enum EAtomId { EAtomId_Test };
const int SIZE=1000;
int StringFormat(char * s
, size_t i_destSizeChars
, const char* i_format
, ...);
int StringFormat(char (&a)[SIZE]
, EAtomId i_format
, ...);
void func()
{
char textBuffer[SIZE];
StringFormat (textBuffer, EAtomId_Test, "hi there");
}
适用的重载决策规则如下(13.3.3):
依次采取以下各项:
功能1:
功能2:
依次比较每个转化次数:
因此,功能1和功能2对于所有转换都不是最好,因此调用不明确。