Search code examples
c++classconstructornullptr

Issue with NULL and 0 behaving the same way


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.


Solution

  • 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;
    }