10

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

6
  • 2
    If an int object has a value 97, there is no special label or designation of any kind that tells you whether it's really the value 97, or 'a'. C++ simply doesn't work this way. It's 97. That's all you know. Commented Jun 13, 2020 at 22:23
  • Your use of numeric_limits is very confused—it’s checking the argument value (converted from whatever type) against a constant true. More study is required. Commented Jul 3, 2020 at 17:21
  • @DavisHerring 'More study is required' on what part exactly. numeric_limits or templates? It is hard for me finding authors with the ability to explain abstract concepts for a simple mind like mine without linguistic encryption - like trying to put everything in 2 words so the reader (me) needs to unpack the whole sentences that the authors compressed/encrypted in 2 words. Or in simple words, It is not easy for me to find authors that are confident enough to use simple descriptions without being afraid of writing simple words. But I keep searching - but maybe you got a tip where too look? Commented Jul 3, 2020 at 21:23
  • @Ivanovic: Calling it encryption is self-defeating: teaching is hard, and C++ is hard, but no one is trying to interfere with your education. The additional study that I recommend is just the basic semantics of the language (see the usual book lists): the test you wrote operates at runtime, independent of the type of the argument expression, and so it just can’t be right. Commented Jul 3, 2020 at 22:01
  • 1
    @Ivanovic: If the test worked as you wanted, it would have to produce different results for integerCheck(1) and integerCheck((char)1), right? But those call the same function with the same parameter value, so how would that work? Commented Jul 4, 2020 at 21:58

3 Answers 3

7

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, ...

Sign up to request clarification or add additional context in comments.

Comments

5

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 

Comments

4

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.