Специализни шаблонца! (udpn) wrote,
Специализни шаблонца!
udpn

Limited

Когда-то я упоминал в комментариях, что мутаторы в классах это идиотизм, и нужно просто уметь использовать правильные типы данных (в языках, где это возможно). Нет, моё мнение ничуть не изменилось. Просто я написал удобный header для этого и хотел бы им поделиться.

UPD Кстати говоря, было бы очень приятно увидеть что-то подобное на Haskell. Я ведь правильно понимаю, что с помощью классов типов (без расширений) решать это нельзя, поскольку возникнут такие же проблемы, как и с двойными instance для Ord?

#ifndef LIMITED
#define LIMITED

#include <iostream>
#include <stdexcept>
#include <string>

template <typename T>
inline bool const_true(T) { return true; }

template <typename T>
inline bool positive(T x) { return x > 0; }

template <typename T>
inline bool nonnegative(T x) { return x >= 0; }

template <typename T, T default = T(), bool is_correct(T) = const_true>
class limited {
    T value;
public:
    operator T() { return value; }
    limited(T const & value = default) : value(value) {
        if (!is_correct(value))
            throw std::domain_error("Domain error");
    }
};

template <typename T, T default, bool is_correct(T)>
std::istream & operator >> (std::istream & istr, limited<T, default, is_correct> & x) {
    T value;
    std::istream & ret = istr >> value;
    x = limited<T, default, is_correct>(value);
    return ret;
}

typedef limited<int, 1, positive> nat;
#endif


Использование:

#include <iostream>
#include <stdexcept>
#include "limited.hpp"
using namespace std;

int main() {
    nat x;
    for (;;) {
        try {
            cin >> x;
            cout << x << endl;
        } catch (domain_error const & e) {
            cout << e.what() << endl;
        }
    }
}
Subscribe
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 24 comments