Синтаксис C ++: if var! = Type int - PullRequest
       11

Синтаксис C ++: if var! = Type int

2 голосов
/ 17 сентября 2009

Я пытаюсь написать оператор if, но не могу найти правильную форму выражения для использования. Я думаю написать что-то вроде этого:

if ( var != type(int) )

Однако я точно не знаю, как это сделать, и этот метод не работает.

Думаю ли я, по крайней мере, в правильном направлении?

Ответы [ 4 ]

18 голосов
/ 17 сентября 2009

Похоже, вы пытаетесь перегрузить функцию:

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

Если вы хотите int -специальное поведение, а затем что-то еще во всех остальных случаях, вы можете использовать шаблоны:

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
}

Согласно вашему комментарию ( "Задача под рукой - простая программа: возьмите два введенных пользователем целых числа и добавьте их. Ограничьте ввод только целыми числами. Я могу сделать это на Python, и я тоже думаю о том же. если num1! = type (int): print «Вы не ввели целое число, введите целое число.» else: continue »), вам нужно что-то вроде этого:

#include <iostream>

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

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

Это уведомит неверный ввод, такой как "@ # $", "r13", но не поймает случаи, такие как "34fg", "12 $ #%", потому что будет читать int и остановитесь на "fg" и "$ #%" соответственно.

Чтобы проверить это, вам нужно прочитать строку ввода, а затем попытаться преобразовать эту строку в нужный вам тип. ( Спасибо, лит ). Это означает, что ваш вопрос более , как этот вопрос :

#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
    {
        // ...
    }
}

Это делает следующее: получает ввод и помещает его в stringstream. Затем после анализа int выведите все оставшиеся пробелы. После этого, если eof равно false, это означает, что есть оставшиеся символы; ввод был неверным.

Это гораздо проще использовать в функции. В другом вопросе, актерский состав был повторно учтен; в этом вопросе мы используем приведение, но завершим ввод вместе с ним.

#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
    {
        // ...
    }
}

Или более обобщенно:

#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
    {
        // ...
    }
}

Это позволяет вам анализировать другие типы с проверкой ошибок.


Если вы согласны с исключениями, используя lexical_cast (либо из boost, либо "faked", смотрите другой вопрос, связанный в коде [такой же, как ссылка выше)), ваш код будет выглядеть примерно так:

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

Я не думаю, что boost имеет безлицензионную версию лексического приведения, поэтому мы можем сделать версию этого кода истинной / ложной, а не исключительной, перехватывая bad_cast следующим образом. Еще раз, это работает либо с boost, либо с пользовательским лексическим приведением. (Все, что делает лексическое приведение и бросает 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;
    }
}

Теперь вернемся к bool результату, за исключением того, что мы избегаем дублирования кода с помощью существующих lexical_cast функций.

Конечно, вы можете выбрать, какой метод вы бы хотели использовать.

9 голосов
/ 17 сентября 2009

C ++ - это статически типизированный язык, означающий, что тип переменной всегда известен компилятору. Поэтому, чтобы объявить var, вы должны указать для него тип, который делает заявление if отправленным вами спорным вопросом. Если вы можете немного подробнее описать задачу, которую вы пытаетесь выполнить, возможно, есть другой путь решения вашей проблемы.

0 голосов
/ 17 сентября 2009

Вы имеете в виду, что у вас есть значение с плавающей точкой и вы хотите знать, является ли оно целым числом или нет?

В этом случае попробуйте это:

#include <math.h>

//...

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

Или, если значение является результатом некоторых вычислений, могут быть небольшие ошибки округления. Затем попробуйте что-то вроде этого:

double x = 4.99999999999;
if(abs(round(x) - x) < 1e-8)
0 голосов
/ 17 сентября 2009

Это верно, требуется больше информации, если вы ищете эквивалент оператора instanceOf в Java, его нет, если вы не используете RTTI и typeid.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...