How do I detect if anything but an integer is passed to my class constructor?

742 Views Asked by At

Fair and simple: How do I check if anything else but an integer is passed to my class in c++?

If I pass f.e. a char 'a' my class gets number 97 in ascii.

I tried std::numeric_limits but I don't get why it is not detecting integers:

#include <iostream>
#include <limits>

class integerCheck
{
public:
    integerCheck(int value)
    {
       if((value != std::numeric_limits<int>::is_integer))
           return;

       std::cout << value << std::endl;
    }
};

int main()
{
    integerCheck valInt(88);
    integerCheck valChar('a');
    integerCheck valFloat(13.44f);

    return 0;
}

I found this Post working with std::enable_if but I can't imagine there is no way to detect wrong input even in c++20 but wrapping everything in a template.

What am I missing, what should I look/search for to detect anything but an integer value? Thanks upfront

3

There are 3 best solutions below

0
asmmo On BEST ANSWER

Delete the constructor taking chars and make the ctor explicit to prevent accepting floats as follows

class integerCheck
{
public:
    explicit integerCheck(int value)
    {

        std::cout << value << std::endl;
    }
    integerCheck(char ) = delete;
};

This doesn't allow the two following ctors to compile

integerCheck valChar('a');
integerCheck valFloat(13.44f);

I think the following will be better to prevent all of types except int.

class integerCheck
{
public:
    explicit integerCheck(int value)
    {

        std::cout << value << std::endl;
    }

    template<class T>
    integerCheck(T ) = delete;
};

Notice that the past code doesn't prevent the est of the integral types like long, size_t, short, ...

0
Igor Tandetnik On

Something along these lines, perhaps:

class integerCheck
{
public:
    // Arguments of type other than `int` go here.
    template <typename T>
    integerCheck(T) {}

    integerCheck(int value) {
       std::cout << value << std::endl;
    }
};
0
Remy Lebeau On

Your constructor takes only int values as input. A char is an integral type, so it is implicitly convertible to int. So are floating point types.

And your use of std::numeric_limits<T>::is_integer doesn't work because it is true when T is int, like you are hard-coding. But it would also be true for other integral types too, including char.

If you want to avoid implicit conversions, you could pass the int by a non-const reference, eg

integerCheck(int &value) {
    std::cout << value << std::endl;
}

However, that means you can't pass in integer literals, either. Only int variables.

A better solution is to make integerCheck() use a template parameter, and then you can check the type of the template that the compiler deduces from the input, eg:

#include <type_traits>

template<typename T>
integerCheck(const T &value) {
    if constexpr (std::is_same_v<T, int>) {
        std::cout << value << std::endl;
    }
}
integerCheck valInt(88); // T=int
integerCheck valChar('a'); // T=char
integerCheck valFloat(13.44f); // T=float