2015-05-20 2 views
0

У меня есть класс шаблонов, который может принимать все типы типов: int, double и т. Д. Я хочу проверить, введен ли пользователь правильный тип. Если объект был создан с помощью int, пользователь должен ввести int, если он был с двойным, он должен ввести double и так далее. Я хочу иметь возможность делать это независимо от того, поступает ли вход от файла или клавиатуры. У меня есть 2 вопроса.Проверьте правильность ввода

  1. Должен ли я выполнять проверку в отношении перегрузки оператора «>>»?
  2. Как мне проверить? Создать функцию шаблона, которая проверяет тип какого-либо типа?

Я хочу что-то вроде этого:

template <class Ttype> 
class foo 
{ 
    Ttype a,b,c; 
    friend istream &operator>> <>(istream &input, foo<Ttype> &X); 
    //methods 
}; 

template <class Ttype> istream &operator>>(istream &input, foo<Ttype> &X) 
{ 
    //check if X.a,X.b,X.c are of Ttype 
    input>>X.a>>X.b>>X.c; 
} 

int main() 
{ 
    foo<int> a; 
    cin>>a; 

    foo<double> b; 
    cin>>b; 

    return 0; 
} 
+0

'X.a' должен быть' Ttype', потому что вы его объявили. Если вы действительно хотите проверить, что вы можете 'static_assert (std :: is_same :: value," not the same ");' но это никогда не будет срабатывать. –

+0

вы можете использовать boost :: spirit, см. [Здесь] (http://www.boost.org/doc/libs/1_58_0/libs/spirit/doc/html/spirit/abstracts/attributes/primitive_attributes.html) и [ здесь] (http://www.boost.org/doc/libs/1_58_0/libs/spirit/doc/html/spirit/qi/reference/numeric.html) –

ответ

1

Вы не можете проверить вход, прежде чем прочитать его. Единственное, о чем я могу думать, это прочитать ввод в строку (которая всегда будет работать для текстовых файлов или stdin) и попытаться преобразовать ее в ваш ожидаемый тип. При конвертации вы можете искать исключения.

+0

И как проверить, соответствуют ли типы? Я использую typeinfo для Ttype? – Andy

+0

Просто используйте метод преобразования и проверьте, не возникли ли исключения. Вы можете специализировать свои функции шаблона для нескольких типов и вызывать правильный метод преобразования в каждом (например, 'atoi' /' atof' или некоторый эквивалент STL, если он включен). –

+0

ни одна из этих функций не выдает исключения. –

1

Кажется, все, что вы хотите, это попытаться прочитать из istream и сбой, если чтение не сработает. В этом случае вы можете использовать неявное bool-подобие istream после операции извлечения.

template <class T> 
class Foo { 
    T a,b,c; 
    friend std::istream& operator>>(std::istream& input, Foo& X) { 
     if (!(input >> X.a >> X.b >> X.c)) { // examine the istream 
     std::cerr << "extraction failed\n"; 
     } 
     return input; 
    } 
} 
+0

Я ценю это решение. Но еще две мысли. Я не совсем уверен, но разве это не вызвало бы проблемы для последней операции чтения (EOF)? Причина EOF также установит failbit, но это не настоящая ошибка. Возможно, я ошибаюсь. Возможно, дополнительная проверка поможет определить, был ли это EOF. Что-то вроде проверки явно 'fail()', и если это правда, проверьте также, не было ли это 'eof()'. Вторая мысль. Не произойдет ли это, например, 'int', если входной сигнал такой же, как' 5.0'? –

+0

'eof' не установлен, пока вы не попытаетесь прочитать * за пределами * конца потока. Если вы введете что-то вроде «1 2.0 3», это провалится, как ожидалось, если вы сделали «1 2 3.5», это будет успешным, но оставить «.5» в потоке. Если вы хотите обойти это, тогда вам придется потреблять входные данные в виде строк .. как именно перейти оттуда не самый ясный. Вы можете создать поток строк для каждой строки и проверить, используется ли весь поток. –

Смежные вопросы