SD.
SD.

Reputation: 3109

C++ syntax question: if var != type int

I am trying to write an if statement but cannot find the proper expression form to use. I'm thinking of writing something like this:

if ( var != type(int) )

However, I am unsure exactly how to go about doing this, and this method does not work.

Am I at least thinking along the right lines?

Upvotes: 3

Views: 12607

Answers (4)

GManNickG
GManNickG

Reputation: 504103

It sounds like you're trying to overload a function:

void foo(int i)
{
    // stuff
}

void foo(float f)
{
    // stuff
}

int main(void)
{
    int i = 10;
    float f = 1.0f;

    foo(i); // calls foo(int)
    foo(f); // calls foo(float)
}

If you want int-special behavior and then something else in all other cases, you can use templates:

template <typename T>
void foo(T t)
{
    // T is something
}

template <>
void foo(int i)
{
    // for int's only
}

int main(void)
{
    int i = 10;
    float f = 1.0f;
    double d = 2.0;

    foo(i); // calls specialized foo
    foo(f); // calls generic foo
    foo(d); // calls generic foo
}

According to your comment ("Task at hand is a simple program: Take two user inputted integers and add them. Restrict input to integer only. I can do it in Python and I am thinking too along those lines. if num1 != type(int): print "You did not enter an integer, please enter a integer." else: continue"), you want something like this:

#include <iostream>

int main(void)
{
    int i;
    std::cin >> i;

    if (std::cin.fail())
    {
        std::cout << "Not valid!" << std::endl;
    }
    else
    {
        // ...
    }
}

This will notify invalid input such as "@#$", "r13", but does not catch cases such as "34fg", "12$#%", because it will read the int, and stop at "fg" and "$#%", respectively.

To check that, you will have to read in a line of input, and then try to convert that line into the type you want. (Thanks, litb). That means your question is more like this question:

#include <iostream>
#include <sstream>
#include <string>

int main(void)
{
    std::string input;
    std::getline(std::cin, input);

    std::stringstream ss(input);
    int i;
    ss >> i;

    if (ss.fail() || !(ss >> std::ws).eof())
    {
        std::cout << "Not valid!" << std::endl;
    }
    else
    {
        // ...
    }
}

This does the following: get input, and put it into a stringstream. Then after parsing the int, stream out any remaining white space. After that, if eof is false, this means there are left-over characters; the input was invalid.

This is much easier to use wrapped in a function. In the other question, the cast was re-factored away; in this question we're using the cast, but wrapping the input along with it.

#include <iostream>
#include <sstream>
#include <string>

bool parse_int(int& i)
{
    std::string input;
    std::getline(std::cin, input);

    std::stringstream ss(input);
    ss >> i;

    return !(ss.fail() || !(ss >> std::ws).eof());
}

int main(void)
{
    int i;

    if (!parse_int(i))
    {
        std::cout << "Not valid!" << std::endl;
    }
    else
    {
        // ...
    }
}

Or more generically:

#include <iostream>
#include <sstream>
#include <string>

template <typename T>
bool parse_type(T& t)
{
    std::string input;
    std::getline(std::cin, input);

    std::stringstream ss(input);
    ss >> t;

    return !(ss.fail() || !(ss >> std::ws).eof());
}

int main(void)
{
    int i;

    if (!parse_type(i))
    {
        std::cout << "Not valid!" << std::endl;
    }
    else
    {
        // ...
    }
}

This let's you parse other types with error checking.


If you're okay with exceptions, using lexical_cast (either from boost, or "faked", see the other question linked in-code [same as above link]), your code would look something like this:

#include <iostream>
#include <sstream>
#include <string>

/* Faked lexical-cast from question:
https://stackoverflow.com/questions/1243428/convert-string-to-int-with-bool-fail-in-c/
*/
template <typename T>
T lexical_cast(const std::string& s)
{
    std::stringstream ss(s);

    T result;
    if ((ss >> result).fail() || !(ss >> std::ws).eof())
    {
        throw std::bad_cast("Bad cast.");
    }

    return result;
}


template <typename T>
T parse_type(void)
{
    std::string input;
    std::getline(std::cin, input);

    return lexical_cast<T>(input);
}

int main(void)
{
    try
    {
        int i = parse_type<int>();
        float f = parse_type<float>();
    }
    catch (const std::exception& e)
    {
        std::cout << e.what() << std::endl;
    }
}

I don't think boost has a no-throw version of lexical cast, so we can make a true/false rather than exception version of this code by catching bad_cast's, as follows. Once again, this works with either boost or a custom lexical cast. (Anything that does a lexical cast and throws bad_cast):

#include <iostream>
#include <sstream>
#include <string>

/* Faked lexical-cast from question:
https://stackoverflow.com/questions/1243428/convert-string-to-int-with-bool-fail-in-c/
*/
template <typename T>
T lexical_cast(const std::string& s)
{
    std::stringstream ss(s);

    T result;
    if ((ss >> result).fail() || !(ss >> std::ws).eof())
    {
        throw std::bad_cast("Bad cast.");
    }

    return result;
}


template <typename T>
bool parse_type(T& t)
{
    std::string input;
    std::getline(std::cin, input);

    try
    {
        t = lexical_cast<T>(input);

        return true;
    }
    catch (const std::bad_cast& e)
    {
        return false;
    }
}

int main(void)
{
    int i;
    if (!parse_type(i))
    {
        std::cout << "Bad cast." << std::endl;
    }
}

Now it's back to a bool result, except we avoid code duplication by using existing lexical_cast functions.

You can of course choose which method you would like to use.

Upvotes: 18

fbrereto
fbrereto

Reputation: 35935

C++ is a statically-typed language, meaning that the type of a variable is known by the compiler at all times. In order to declare var therefore, you have to specify a type for it, which makes the if statement you posted a moot point. If you can describe a bit more the task you are trying to accomplish, perhaps there is another path to solve your problem.

Upvotes: 9

CAdaker
CAdaker

Reputation: 14711

Do you mean that you have a floating-point value and want to know if it's an integer or not?

In that case, try this:

#include <math.h>

//...

double x = 5.0;
if(round(x) == x) {
   // x has an integer value
}

Or, if the value is the result of some computation, there might be small rounding errors. Then try something like this:

double x = 4.99999999999;
if(abs(round(x) - x) < 1e-8)

Upvotes: 0

Murali VP
Murali VP

Reputation: 6427

That is right, more information is needed, if you are looking for an equivalent of "instanceOf" operator of Java, there isn't one, unless you use RTTI and typeid.

Upvotes: 0

Related Questions