在下面的示例中,0
它以一种特殊的方式运行:它选择与示例函数调用所期望的不同的重载。我想知道为什么。我的理解也如下。
#include <iostream>
template<typename T>
void f(T a) {
std::cout << "first" << std::endl;
}
template<typename T>
void f(T* a) {
std::cout << "second" << std::endl;
}
int main()
{
f(0);
f<size_t>(0);
f<size_t>(0UL);
f(1);
f<size_t>(1);
}
Run Code Online (Sandbox Code Playgroud)
输出:
first
second
first
first
first
Run Code Online (Sandbox Code Playgroud)
我的理解:
f(0)
- 模板参数推导,整数文字0
是int
类型,因此f
选择第一个T=int
f<size_t>(0)
-带有整数提升的显式模板实例化,选择的类型是T=size_t
,选择第一个函数并从到提升0
(我在这里错了)int
size_t
f<size_t>(0UL)
- 与上面相同,但没有升级(0 已经是 type size_t
)
f(1)
- 与 …
c++ templates function-templates overload-resolution template-argument-deduction
这是标准算术转换的简单展示:
// Example program
#include <iostream>
using namespace std;
int main()
{
unsigned long a = 0;
int b = 1;
long long c = -1;
cout << (c < a*b) << endl;
}
Run Code Online (Sandbox Code Playgroud)
godbolt 返回 0,cpp.sh 返回 1。
标准(https://en.cppreference.com/w/cpp/language/usual_arithmetic_conversions)说:
第四阶段...
- 如果U的整数转换等级大于或等于S的整数转换等级,则C是U。
- 否则,如果S可以代表U的所有值,则C就是S。
- 否则,C 是与 S 对应的无符号整数类型。
哪个编译器是错误的,为什么?
我一直认为下一个例子是未定义的行为(访问数组越界):
int main()
{
int* a= new int[3];
a[0] = 100;
a++;
unsigned long index = 0;
printf("%d\n", a[-1]);
printf("%d\n", a[index - 1]);
printf("%ul\n", index - 1);
}
Run Code Online (Sandbox Code Playgroud)
然而,这个输出很好:
100
100
4294967295l
Run Code Online (Sandbox Code Playgroud)
为什么下标运算符不会发生下溢?