NULL 和 0 的行为方式相同
Issue with NULL and 0 behaving the same way
我正在研究 class :
#include <iostream>
#include <list>
using namespace std;
class Int{
list <int64_t> data;
bool sign;
public:
Int(int64_t val = 0) : sign(false) {
cout << "Int(int) called\n";
}
Int(const char* str): sign(false) {
cout << "Int(const char* called)\n";
}
};
int main(){
Int a = "328739"; // line 1, ok
Int a2 = "ehfjhs"; // line 2, ok
Int a3 = 4338974; // line 3, ok
Int a4 = 0; //line 4, Issue
return 0;
}
一切正常,除了第 4 行。
我一执行 Int a4 = 0;
,就会调用构造函数 Int(const char* str)
,因为 0
等同于 NULL
。但我希望 Int(int64_t val = 0)
被调用。
我可以做的一个简单的修复是Int a4 = int(0);
,这在另一方面是可以的。但我想让它更灵活,所以 0 只触发 Int(int64_t val = 0)
。
这里的关键点是 0
不是 int64_t
,因此它必须经过隐式转换才能在您的任一构造函数中使用。两个构造函数在这里同样有效。 gcc 和 clang 实际上将歧义标记为错误,而不是像您遇到的那样任意选择一个错误。
0
的类型是 int
,所以如果你有一个 int
构造函数,它将绑定到 0
而无需事先进行任何隐式转换,这解决歧义:
class Int{
list <int64_t> data;
bool sign;
public:
Int(int64_t val = 0) : sign(false) {
cout << "Int(int) called\n";
}
Int(int val) : sign(false) {
cout << "Int(int) called\n";
}
Int(const char* str): sign(false) {
cout << "Int(const char* called)\n";
}
};
作为其他答案的替代方案,您可以制作一个接受任何整数类型的模板构造函数。这将解决歧义并另外适用于任何整数类型或文字。
#include <iostream>
#include <list>
using namespace std;
class Int{
list <int64_t> data;
bool sign;
public:
template <typename T, std::enable_if_t<std::is_integral_v<T>>* = nullptr>
Int(T val = 0) : sign(false) {
cout << "Int(Integral) called\n";
}
Int(const char* str): sign(false) {
cout << "Int(const char* called)\n";
}
};
int main(){
Int a = "328739"; // line 1, ok
Int a2 = "ehfjhs"; // line 2, ok
Int a3 = 4338974; // line 3, ok
Int a4 = 0; // line 4, ok
return 0;
}
我正在研究 class :
#include <iostream>
#include <list>
using namespace std;
class Int{
list <int64_t> data;
bool sign;
public:
Int(int64_t val = 0) : sign(false) {
cout << "Int(int) called\n";
}
Int(const char* str): sign(false) {
cout << "Int(const char* called)\n";
}
};
int main(){
Int a = "328739"; // line 1, ok
Int a2 = "ehfjhs"; // line 2, ok
Int a3 = 4338974; // line 3, ok
Int a4 = 0; //line 4, Issue
return 0;
}
一切正常,除了第 4 行。
我一执行 Int a4 = 0;
,就会调用构造函数 Int(const char* str)
,因为 0
等同于 NULL
。但我希望 Int(int64_t val = 0)
被调用。
我可以做的一个简单的修复是Int a4 = int(0);
,这在另一方面是可以的。但我想让它更灵活,所以 0 只触发 Int(int64_t val = 0)
。
这里的关键点是 0
不是 int64_t
,因此它必须经过隐式转换才能在您的任一构造函数中使用。两个构造函数在这里同样有效。 gcc 和 clang 实际上将歧义标记为错误,而不是像您遇到的那样任意选择一个错误。
0
的类型是 int
,所以如果你有一个 int
构造函数,它将绑定到 0
而无需事先进行任何隐式转换,这解决歧义:
class Int{
list <int64_t> data;
bool sign;
public:
Int(int64_t val = 0) : sign(false) {
cout << "Int(int) called\n";
}
Int(int val) : sign(false) {
cout << "Int(int) called\n";
}
Int(const char* str): sign(false) {
cout << "Int(const char* called)\n";
}
};
作为其他答案的替代方案,您可以制作一个接受任何整数类型的模板构造函数。这将解决歧义并另外适用于任何整数类型或文字。
#include <iostream>
#include <list>
using namespace std;
class Int{
list <int64_t> data;
bool sign;
public:
template <typename T, std::enable_if_t<std::is_integral_v<T>>* = nullptr>
Int(T val = 0) : sign(false) {
cout << "Int(Integral) called\n";
}
Int(const char* str): sign(false) {
cout << "Int(const char* called)\n";
}
};
int main(){
Int a = "328739"; // line 1, ok
Int a2 = "ehfjhs"; // line 2, ok
Int a3 = 4338974; // line 3, ok
Int a4 = 0; // line 4, ok
return 0;
}