任何人都可以帮助我理解以下代码
#include <iostream>
void foo(const char * c)
{
std::cout << "const char *" << std::endl;
}
template <size_t N>
void foo(const char (&t) [N])
{
std::cout << "array ref" << std::endl;
std::cout << sizeof(t) << std::endl;
}
int main()
{
const char t[34] = {'1'};
foo(t);
char d[34] = {'1'};
foo(d);
}
Run Code Online (Sandbox Code Playgroud)
输出是
const char *
array ref
34
Run Code Online (Sandbox Code Playgroud)
为什么第一个foo调用const char *版本?如何让它调用参考版本?
Lig*_*ica 15
转换为const char[N]to const char*被认为是"完全匹配"(主要是为了使文字更容易),并且在两个完全匹配之间,非模板函数优先.
您可以使用enable_if并is_array强制它执行您想要的操作.
强迫它的一种混乱方式可能是:
#include <iostream>
template <typename T>
void foo(const T* c)
{
std::cout << "const T*" << std::endl;
}
template <typename T, size_t N>
void foo(const T (&t) [N])
{
std::cout << "array ref" << std::endl;
}
int main()
{
const char t[34] = {'1'};
foo(t);
char d[34] = {'1'};
foo(d);
}
/*
array ref
array ref
*/
Run Code Online (Sandbox Code Playgroud)
我意识到OP char没有一些通用的T,但是这表明问题在于一个重载是模板而不是另一个.
让我们看看没有模板的这个修改过的例子.
void foo(const char * c)
{
std::cout << "const char *" << std::endl;
}
void foo(const char (&t) [34])
{
std::cout << "const char (&) [34]" << std::endl;
}
int main()
{
const char t[34] = {'1'};
foo(t);
}
Run Code Online (Sandbox Code Playgroud)
我的编译器说重载调用foo是模糊的.这是因为从数组到指针的转换被认为是"精确"转换序列,并不比重载解析的空转换序列更好(标准部分13.3.3.1.1.)
在原始代码中,模板参数N可以推导为34,但随后都是非模板foo(const char*),foo<34>(const char (&)[34])并且在重载决策中被认为是.由于转换规则两者都不比另一个好,因此非模板函数胜过模板函数.
解决问题似乎很棘手.看起来像is_array标题中的模板<type_traits>(如果可能的话,来自C++ 0x,或者如果没有则来自Boost)可能会有所帮助.
| 归档时间: |
|
| 查看次数: |
4548 次 |
| 最近记录: |