I was working on a 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;
}
Everything works fine, except line no 4.
As soon I do Int a4 = 0;
, the constructor Int(const char* str)
is called, as 0
is equivalent to NULL
. But I want Int(int64_t val = 0)
to be called instead.
A simple fix I could make was doing Int a4 = int(0);
that is ok on a side. But I want to make it flexible, so 0 triggers Int(int64_t val = 0)
only.
As an alternative to the other answer, you can make a template constructor that accepts any integral type. This would resolve the ambiguity and additionally work for any integral type or literal.
#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;
}