Жёсткая типизация
От: Chez Россия  
Дата: 19.10.04 11:34
Оценка:
Приветствую всех!

typedef size_t TypedCounterType;
typedef TypedCounterType CountType;
typedef TypedCounterType IndexType;

typedef size_t UntypedCounterType;
typedef UntypedCounterType SizeType;
typedef UntypedCounterType OffsetType;
и далее:
void foo()
{
    IndexType idx = 10;
    OffsetType offs;

    offs = idx; // Как сделать, чтобы это было невозможно (носвместимость типов)
                    // или хотя-бы Warning ?
}

Необязательно именно так, главное чтобы суть идеи сохранилась
Chez, ICQ# 161095094
Re: Жёсткая типизация
От: Аноним  
Дата: 19.10.04 11:38
Оценка:
Здравствуйте, Chez, Вы писали:

C>Приветствую всех!


C>
C>typedef size_t TypedCounterType;
C>typedef TypedCounterType CountType;
C>typedef TypedCounterType IndexType;

C>typedef size_t UntypedCounterType;
C>typedef UntypedCounterType SizeType;
C>typedef UntypedCounterType OffsetType;
C>
и далее:

C>
C>void foo()
C>{
C>    IndexType idx = 10;
C>    OffsetType offs;

C>    offs = idx; // Как сделать, чтобы это было невозможно (носвместимость типов)
C>                    // или хотя-бы Warning ?
C>}
C>

C>Необязательно именно так, главное чтобы суть идеи сохранилась

А в чем суть идеи-то? Можно реализовать TypedCounterType и UntypedCounterType как классы, тогда присваивание по умолчанию работать не будет. typedef не вводит новый тип — только другое имя для уже существующего типа.
Re: Жёсткая типизация
От: jazzer Россия Skype: enerjazzer
Дата: 19.10.04 11:38
Оценка:
Здравствуйте, Chez, Вы писали:

C>Приветствую всех!


C>
C>typedef size_t TypedCounterType;
C>typedef TypedCounterType CountType;
C>typedef TypedCounterType IndexType;

C>typedef size_t UntypedCounterType;
C>typedef UntypedCounterType SizeType;
C>typedef UntypedCounterType OffsetType;
C>
и далее:

C>
C>void foo()
C>{
C>    IndexType idx = 10;
C>    OffsetType offs;

C>    offs = idx; // Как сделать, чтобы это было невозможно (носвместимость типов)
C>                    // или хотя-бы Warning ?
C>}
C>

C>Необязательно именно так, главное чтобы суть идеи сохранилась

только отказаться от typedef и объявить полноценные пользовательские типы
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[2]: Жёсткая типизация
От: Chez Россия  
Дата: 19.10.04 11:51
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>А в чем суть идеи-то? Можно реализовать TypedCounterType и UntypedCounterType как классы, тогда присваивание по умолчанию работать не будет. typedef не вводит новый тип — только другое имя для уже существующего типа.


Хм... Если сделать оператор преобразования типа
class TypedCounterType<size_t id>
{
public:
    operator int() { ... };
    ...
};
// то
typedef TypedCounterType<0> type1;
typedef TypedCounterType<1> type2;

type1 a;
type2 b;

a = b; // Увы, работает  :(
Chez, ICQ# 161095094
Re[3]: Жёсткая типизация
От: Аноним  
Дата: 19.10.04 11:57
Оценка:
Здравствуйте, Chez, Вы писали:

C>Здравствуйте, <Аноним>, Вы писали:


А>>А в чем суть идеи-то? Можно реализовать TypedCounterType и UntypedCounterType как классы, тогда присваивание по умолчанию работать не будет. typedef не вводит новый тип — только другое имя для уже существующего типа.


C>Хм... Если сделать оператор преобразования типа

C>
C>class TypedCounterType<size_t id>
C>{
C>public:
C>    operator int() { ... };
C>    ...
C>};
C>// то
C>typedef TypedCounterType<0> type1;
C>typedef TypedCounterType<1> type2;

C>type1 a;
C>type2 b;

C>a = b; // Увы, работает  :( 
C>



Я, видимо, что-то не так понял, но

class TypedCounterType<size_t id>

не компилируется, а если написать

template<size_t id> class TypedCounterType ...

то

а=b;

выдает ошибку "нет оператора присваивания"
У меня VS.NET 2003
Re[4]: Жёсткая типизация
От: Chez Россия  
Дата: 19.10.04 12:37
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Я, видимо, что-то не так понял, но


А>class TypedCounterType<size_t id>

да, здесь я ошибся. Я имел ввиду вот это:
template<class Type, int id>
class TypedCounterType
{
public:
    operator Type&() { return n; };
    Type n;
};
// то
typedef TypedCounterType<double, 1> type1;
typedef TypedCounterType<double, 2> type2;

type1 a;
type2 b;

a = b; // Увы, работает  :(
Chez, ICQ# 161095094
Re[5]: Жёсткая типизация
От: Аноним  
Дата: 19.10.04 12:46
Оценка:
Все равно не работает: Visual C++ .NET 2003
Re: Жёсткая типизация
От: yxiie Украина www.enkord.com
Дата: 19.10.04 15:53
Оценка: 1 (1)
Здравствуйте, Chez, Вы писали:

C>Приветствую всех!


C>
C>typedef size_t TypedCounterType;
C>typedef TypedCounterType CountType;
C>typedef TypedCounterType IndexType;

C>typedef size_t UntypedCounterType;
C>typedef UntypedCounterType SizeType;
C>typedef UntypedCounterType OffsetType;
C>
и далее:

C>
C>void foo()
C>{
C>    IndexType idx = 10;
C>    OffsetType offs;

C>    offs = idx; // Как сделать, чтобы это было невозможно (носвместимость типов)
C>                    // или хотя-бы Warning ?
C>}
C>

C>Необязательно именно так, главное чтобы суть идеи сохранилась

так подойдет? :

#include <iostream>

template <class T, class ID> 
class wrap {
    typename T data_;
public:
    wrap() {}
  wrap(const T& init): data_(init) {}

    operator typename T() {
        return data_;
    }
};

typedef wrap<int, class id1> type1;
typedef wrap<int, class id2> type2;

int main() {
    type1 a1, b1=5;
    type2 a2=1;

    a1=b1;  // ok
    a1=4;   // ok
    a1=a2;  // не компилится

    std::cout<<a1<<std::endl;
}
... << RSDN@Home 1.1.3 stable >>
Re[2]: Жёсткая типизация
От: McSeem2 США http://www.antigrain.com
Дата: 19.10.04 18:15
Оценка:
Здравствуйте, yxiie, Вы писали:

Y>
Y>#include <iostream>

Y>template <class T, class ID> 
Y>class wrap {
Y>    typename T data_;
Y>public:
Y>    wrap() {}
Y>  wrap(const T& init): data_(init) {}

Y>    operator typename T() {
Y>        return data_;
Y>    }
Y>};

Y>typedef wrap<int, class id1> type1;
Y>typedef wrap<int, class id2> type2;

Y>int main() {
Y>    type1 a1, b1=5;
Y>    type2 a2=1;

Y>    a1=b1;  // ok
Y>    a1=4;   // ok
Y>    a1=a2;  // не компилится

Y>    std::cout<<a1<<std::endl;
Y>}
Y>


А как насчет:
    a1 += 10;
    ++a1;

Все это надоть явно перегружать. Это не просто лишняя работа, иногда это приводит в конфликтам с тем же оператором T(). Вообще, для хорошей переносимости не стоит увлекаться перегрузкой операторов и особенно, типа T().

Что и говорить, не хватает в C++ простого добавления новых типов. Что-то типа:
introduce_type int my_integral;

А так же, чего-нибудь типа такого:
introduce_template std::vector<class T, my_allocator> vector_with_my_allocator<class T>;
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Re[3]: Жёсткая типизация
От: yxiie Украина www.enkord.com
Дата: 19.10.04 18:21
Оценка:
Здравствуйте, McSeem2, Вы писали:

MS>А как насчет:

MS>
MS>    a1 += 10;
MS>    ++a1;
MS>

MS>Все это надоть явно перегружать. Это не просто лишняя работа, иногда это приводит в конфликтам с тем же оператором T(). Вообще, для хорошей переносимости не стоит увлекаться перегрузкой операторов и особенно, типа T().

доработать напильником до полного удовлетворения

MS>Что и говорить, не хватает в C++ простого добавления новых типов. Что-то типа:

MS>
MS>introduce_type int my_integral;
MS>

MS>А так же, чего-нибудь типа такого:
MS>
MS>introduce_template std::vector<class T, my_allocator> vector_with_my_allocator<class T>;
MS>


Да не говори, все тебе чего-то в С++ нехватает, то типов, то препроцессора. Ты случайно не паскалист?
... << RSDN@Home 1.1.3 stable >>
Re[4]: Жёсткая типизация
От: McSeem2 США http://www.antigrain.com
Дата: 19.10.04 18:29
Оценка:
Здравствуйте, yxiie, Вы писали:

Y>Да не говори, все тебе чего-то в С++ нехватает, то типов, то препроцессора.


Не препроцессора, а макро-процессора. Сколько можно талдычить?
Препроцессирование как отдельный процесс — маздай.
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Re[5]: Жёсткая типизация
От: bkat  
Дата: 19.10.04 19:51
Оценка:
Здравствуйте, McSeem2, Вы писали:

MS>Здравствуйте, yxiie, Вы писали:


Y>>Да не говори, все тебе чего-то в С++ нехватает, то типов, то препроцессора.


MS>Не препроцессора, а макро-процессора. Сколько можно талдычить?

MS>Препроцессирование как отдельный процесс — маздай.

Думаю макропроцессор от древнего и уже почти забытого PL/1 тебе бы понравился.
В нем есть и свои встроенные типы данных (включая естественно строковые)
и процедуры с функциями и кажется даже операторы ввода/вывода.
В общем на макропроцессоре PL/1 вполне реально писать самые обычные программы.
Re[3]: Жёсткая типизация
От: jazzer Россия Skype: enerjazzer
Дата: 20.10.04 01:14
Оценка: 14 (1)
Здравствуйте, McSeem2, Вы писали:

MS>Что и говорить, не хватает в C++ простого добавления новых типов. Что-то типа:

MS>
MS>introduce_type int my_integral;
MS>

Если мне память не изменяет, на эту тему есть соответствующий proposal.


MS>А так же, чего-нибудь типа такого:

MS>
MS>introduce_template std::vector<class T, my_allocator> vector_with_my_allocator<class T>;
MS>

А это называется template typedef и такой proposal есть точно.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[6]: Жёсткая типизация
От: McSeem2 США http://www.antigrain.com
Дата: 20.10.04 01:48
Оценка:
Здравствуйте, bkat, Вы писали:

B>Думаю макропроцессор от древнего и уже почти забытого PL/1 тебе бы понравился.


Почему "бы"? Именно он мне и нравился Но это было в 85-86 годах прошлого века.
Потом пошел MACRO-11, который был значительно хуже. Потом — сишный, который просто халтура по сравнению с MACRO-11. Такие дела...
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Re: Жёсткая типизация
От: folk Россия  
Дата: 20.10.04 05:48
Оценка:
Здравствуйте, Chez, Вы писали:

C>Приветствую всех!


C>
C>typedef size_t TypedCounterType;
C>typedef TypedCounterType CountType;
C>typedef TypedCounterType IndexType;

C>typedef size_t UntypedCounterType;
C>typedef UntypedCounterType SizeType;
C>typedef UntypedCounterType OffsetType;
C>
и далее:

C>
C>void foo()
C>{
C>    IndexType idx = 10;
C>    OffsetType offs;

C>    offs = idx; // Как сделать, чтобы это было невозможно (носвместимость типов)
C>                    // или хотя-бы Warning ?
C>}
C>

C>Необязательно именно так, главное чтобы суть идеи сохранилась

Для целочисленных проще всего использовать перечисления, приведение enum->integer неявное, а приведение integer->enum явное.
enum IndexType { IndexTypeMin = 0, IndexTypeMax = UINT_MAX };
enum OffsetType { OffsetTypeMin = 0, OffsetTypeMax = UINT_MAX };

void foo()
{
    IndexType idx = (IndexType)10;
    OffsetType offs;

    offs = idx; // error
}
На самом деле, люди не читают газеты, они принимают их каждое утро, так же как ванну. ©Маршалл Мак-Льюэн
Re[3]: Жёсткая типизация
От: folk Россия  
Дата: 20.10.04 06:01
Оценка: +1
Здравствуйте, McSeem2, Вы писали:

MS>Что и говорить, не хватает в C++ простого добавления новых типов. Что-то типа:

MS>
MS>introduce_type int my_integral;
MS>

Какие операции с my_integral должны унаследоваться от int, а какие нет?
На самом деле, люди не читают газеты, они принимают их каждое утро, так же как ванну. ©Маршалл Мак-Льюэн
Re: Жёсткая типизация
От: Anton V. Kolotaev  
Дата: 20.10.04 07:02
Оценка:
Здравствуйте, Chez, Вы писали:

C>
C>typedef size_t TypedCounterType;
C>typedef TypedCounterType CountType;
C>typedef TypedCounterType IndexType;

C>typedef size_t UntypedCounterType;
C>typedef UntypedCounterType SizeType;
C>typedef UntypedCounterType OffsetType;
C>
и далее:

C>
C>void foo()
C>{
C>    IndexType idx = 10;
C>    OffsetType offs;

C>    offs = idx; // Как сделать, чтобы это было невозможно (носвместимость типов)
C>                    // или хотя-бы Warning ?
C>}
C>

C>Необязательно именно так, главное чтобы суть идеи сохранилась


Я, например, иногда в подобных случаях делаю так:

enum TypeCounterType {};

inline TypeCounterType toTypeCounterType(int i) { return static_cast<TypeCounterType>(i); }

// определим нужные нам операторы (их оказывается, как правило, немного)
inline TypeCounterType & operator ++ (TypeCounterType & t)
{
    return t = toTypeCounterType(t + 1);
}

enum UntypedCounterType {};
Re[2]: Жёсткая типизация
От: Chez Россия  
Дата: 20.10.04 07:39
Оценка:
Здравствуйте, yxiie, Вы писали:


Y>так подойдет? :

не совсем:

#include <iostream>

template <class T, class ID> 
class wrap {
    typename T data_;
public:
    wrap() {}
  wrap(const T& init): data_(init) {}

    operator typename T() {
        return data_;
    }
};

typedef wrap<int, class id1> type1;
typedef wrap<int, class id2> type2;

int main() {
    type1 a1, b1=5;
    type2 a2=1;

    a1=b1;  // ok
    a1=4;   // ok
    a1=a2;  // не компилится
    int r = a1 + a2; // компилится

    std::cout<<a1<<std::endl;
}
Chez, ICQ# 161095094
Re[4]: Жёсткая типизация
От: jazzer Россия Skype: enerjazzer
Дата: 20.10.04 09:47
Оценка:
Здравствуйте, folk, Вы писали:

F>Здравствуйте, McSeem2, Вы писали:


MS>>Что и говорить, не хватает в C++ простого добавления новых типов. Что-то типа:

MS>>
MS>>introduce_type int my_integral;
MS>>

F>Какие операции с my_integral должны унаследоваться от int, а какие нет?

очевидно, все, но с заменой int на my_integral.
и, естественно, запрет неявного преобразования одного в другое.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[3]: Жёсткая типизация
От: vdimas Россия  
Дата: 20.10.04 15:57
Оценка: 1 (1)
Здравствуйте, Chez, Вы писали:

Y>>так подойдет? :

C>не совсем:

убрать operator typename T(),

добавить тонну других операторов (как мемберов, так и френдов),
включая потоковые << >>,

тогда пойдет.

Давно бы кто-нить сваял для числовых типов, да выложил для общего пользования.
иногда нада.
Re[5]: Жёсткая типизация
От: folk Россия  
Дата: 20.10.04 22:05
Оценка:
Здравствуйте, jazzer, Вы писали:

MS>>>Что и говорить, не хватает в C++ простого добавления новых типов. Что-то типа:

MS>>>
MS>>>introduce_type int my_integral;
MS>>>

F>>Какие операции с my_integral должны унаследоваться от int, а какие нет?

J>очевидно, все, но с заменой int на my_integral.

J>и, естественно, запрет неявного преобразования одного в другое.

Кому как, мне не очевидно.
Можно выделить 3 вида операций, составляющих интерфейс типа — функции-члены, свободные функции и встроенные операторы (непонятно чем они являются, поэтому лучше выделить их в отдельную группу).
Так какие из них должны наследоваться? Будет ли унаследованый встроенный оператор оставаться встроенным оператором (можно ли будет брать его адрес)? Можно ли инициализировать my_integral аргументом int? Должны ли унаследоваться неявные преобразования в long/unsigned int?
На самом деле, люди не читают газеты, они принимают их каждое утро, так же как ванну. ©Маршалл Мак-Льюэн
Re[6]: Жёсткая типизация
От: jazzer Россия Skype: enerjazzer
Дата: 21.10.04 07:12
Оценка:
Здравствуйте, folk, Вы писали:

F>Здравствуйте, jazzer, Вы писали:


MS>>>>Что и говорить, не хватает в C++ простого добавления новых типов. Что-то типа:

MS>>>>
MS>>>>introduce_type int my_integral;
MS>>>>

F>>>Какие операции с my_integral должны унаследоваться от int, а какие нет?

J>>очевидно, все, но с заменой int на my_integral.

J>>и, естественно, запрет неявного преобразования одного в другое.

F>Кому как, мне не очевидно.

F>Можно выделить 3 вида операций, составляющих интерфейс типа — функции-члены, свободные функции и встроенные операторы (непонятно чем они являются, поэтому лучше выделить их в отдельную группу).
F>Так какие из них должны наследоваться? Будет ли унаследованый встроенный оператор оставаться встроенным оператором (можно ли будет брать его адрес)? Можно ли инициализировать my_integral аргументом int? Должны ли унаследоваться неявные преобразования в long/unsigned int?

Что значит — наследоваться? никто о наследовании не говорит. Речь идет о слегка продвинутом typedef.
Т.е. my_integral должен вести себя как int во всех ситуациях, кроме неявных преобразований — они запрещены.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[4]: Жёсткая типизация
От: ssm Россия  
Дата: 21.10.04 07:34
Оценка:
Здравствуйте, vdimas, Вы писали:



V>Давно бы кто-нить сваял для числовых типов, да выложил для общего пользования.

V>иногда нада.


//  Copyright 1997-2003 Adobe Systems Incorporated. All rights reserved.
//  
//  NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance 
//  with the terms of the Adobe license agreement accompanying it.  If you have received
//  this file from a source other than Adobe, then your use, modification, or 
//  distribution of it requires the prior written permission of Adobe.


// ===================================================================================
//    PODTraits
//         POD stands for Plain Old Data
// ===================================================================================

struct base_type  { typedef  base_type   data_type;};
struct object_type{ typedef  object_type data_type;};


/** 32 bit signed integer */
typedef long int32;

/** 32 bit unsigned integer */
typedef unsigned long uint32;


/** IDType is the underlying base type used for representing any type that is an 
    InDesign ID-space. An ID-space is an integer composed of a plug-in prefix, 
    plus a one-byte offset. Each identifier within the id-space is unique. We
    use IDType as a base class in order to detect mismatches between them at 
    runtime. For instance, if you pass a ClassID to something that expects an
    IID, that will cause a compile time error instead of a (relatively more costly
    to fix) runtime error.
    
    IDTypes can be used pretty much interchangeably as if they were integers. The
    exceptions to this rule are if they are being used in a switch statement, and
    when you are reading them in or out of resources. For cases where you simply 
    must have an integer, we supply the Get() function.
*/
template<class T>
class IDType
{
    public:
        typedef base_type data_type;
        typedef int32 difference_type;
        typedef uint32 value_type;

        IDType() : fIDInt(0) {}
        //~IDType() {}
        IDType(value_type sourceInt) : fIDInt(sourceInt) {}
        IDType(const IDType& sourceIDClass) : fIDInt(sourceIDClass.fIDInt) {}
        IDType& operator=(const value_type& sourceInt) {fIDInt = sourceInt; return *this;}
        IDType& operator=(const IDType& sourceIDClass) {fIDInt = sourceIDClass.fIDInt; return *this;}

        bool operator>(const IDType& rhs) const { return fIDInt > rhs.fIDInt; }
        bool operator>(const value_type& rhs) const { return fIDInt > rhs; }
        friend bool operator>(const value_type& lhs, const IDType<T>& rhs) { return lhs > rhs.fIDInt; }

        bool operator<(const IDType& rhs) const { return fIDInt < rhs.fIDInt; }
        bool operator<(const value_type& rhs) const { return fIDInt < rhs; }
        friend bool operator<(const value_type& lhs, const IDType<T>& rhs) { return lhs < rhs.fIDInt; }

        bool operator<=(const IDType& rhs) const { return !(fIDInt > rhs.fIDInt); }
        bool operator<=(const value_type& rhs) const { return !(fIDInt > rhs); }
        friend bool operator<=(const value_type& lhs, const IDType<T>& rhs) { return !(lhs > rhs.fIDInt); }

        bool operator>=(const IDType& rhs) const { return !(fIDInt < rhs.fIDInt); }
        bool operator>=(const value_type& rhs) const { return !(fIDInt < rhs); }
        friend bool operator>=(const value_type& lhs, const IDType<T>& rhs) { return !(lhs < rhs.fIDInt); }

        bool operator==(const IDType& rhs) const { return fIDInt == rhs.fIDInt; }
        friend bool operator==(const value_type& lhs, const IDType<T>& rhs) { return lhs == rhs.fIDInt; }

        bool operator!=(const IDType& rhs) const { return !(fIDInt == rhs.fIDInt); }
        bool operator!=(const value_type& rhs) const { return !(fIDInt == rhs); }
        friend bool operator!=(const value_type& lhs, const IDType<T>& rhs) { return !(lhs == rhs.fIDInt); }

        IDType& operator+=(const difference_type& rhs) { fIDInt += rhs; return *this; }
        friend IDType<T> operator+(const IDType<T>& lhs, const difference_type& rhs) { return IDType<T>(lhs) += rhs; }
        friend IDType<T> operator+(const IDType<T>& lhs, const IDType<T>& rhs) { return IDType<T>(lhs) += rhs.fIDInt; }
        friend IDType<T> operator+(const difference_type& lhs, const IDType<T> rhs) { return IDType<T>(rhs) += lhs; }

        // prefix
        IDType& operator++() { *this += 1; return *this; }
        // postfix
        const IDType operator++(int) { IDType oldValue = *this; ++(*this); return oldValue; }

        IDType& operator-=(const IDType& rhs) { fIDInt - rhs.fIDInt; return *this; }
        IDType& operator-=(const difference_type& rhs) { fIDInt - rhs; return *this; }
        friend IDType<T> operator-(const difference_type& lhs, IDType<T> rhs) { return IDType<T>(rhs) -= lhs; }
        friend difference_type operator-(const IDType<T>& lhs, const difference_type& rhs) { return lhs.fIDInt - rhs; }
        friend difference_type operator-(const IDType<T>& lhs, const IDType<T>& rhs) { return lhs.fIDInt - rhs.fIDInt; }

        // prefix
        IDType& operator--() { *this -= 1; return *this; }
        // postfix
        const IDType operator--(int) { IDType oldValue = *this; --(*this); return oldValue; }

        value_type operator>>(const int& rhs) const { return fIDInt >> rhs; }
        value_type operator<<(const int& rhs) const { return fIDInt << rhs; }

        value_type operator&(const value_type& rhs) const { return fIDInt & rhs; }
        friend value_type operator&(const value_type& lhs, const IDType<T>& rhs) { return IDType<T>(rhs) & lhs; }

        value_type operator|(const value_type& rhs) { return fIDInt | rhs; }
        friend value_type operator|(const value_type& lhs, const IDType<T>& rhs) { return IDType<T>(rhs) | lhs; }

        IDType& operator|=(const value_type& rhs) { fIDInt |= rhs; return *this; }
//        friend value_type operator|=(const value_type& lhs, const IDType<T>& rhs) { lhs |= rhs.fIDInt; return lhs; }

        value_type& Get() { return fIDInt; }
        inline const value_type& Get() const { return fIDInt; }

        bool IsValid() const { return (fIDInt != 0); }

//        operator uint32&() { return fIDInt; }
//        operator uint32() { return fIDInt; }

    private:
        value_type fIDInt;
};
Re[5]: Жёсткая типизация
От: ssm Россия  
Дата: 21.10.04 08:00
Оценка:
Здравствуйте, ssm, Вы писали:

ssm>
...
ssm>


и с учетом этого тогда так:


struct TypedCounterTypeTag{};
typedef IDType<TypedCounterTypeTag> CountType;
typedef IDType<TypedCounterTypeTag> IndexType;

struct UntypedCounterTypeTag{};
typedef IDType<UntypedCounterTypeTag> SizeType;
typedef IDType<UntypedCounterTypeTag> OffsetType;
Re[5]: Жёсткая типизация
От: vdimas Россия  
Дата: 21.10.04 09:31
Оценка:
Здравствуйте, ssm, Вы писали:

уже близко,

пара замечаний:

        IDType(value_type sourceInt)


нужен explicit, и многое соответственно переделать,
так же вынести value_type и difference_type в параметр шаблона.
Re[6]: Жёсткая типизация
От: ssm Россия  
Дата: 21.10.04 09:43
Оценка:
Здравствуйте, vdimas, Вы писали:

V>
V>        IDType(value_type sourceInt)
V>


V>нужен explicit,

ну это спорный вопрос, мое ИМХО он будет только мешать
Re[2]: Жёсткая типизация
От: vdimas Россия  
Дата: 21.10.04 10:18
Оценка:
Здравствуйте, folk, Вы писали:

угу, тоже вариант.

однако надо будет наворачивать нечто типа:

IndexType inline operator + (IndexType i1, IndexType i2)
{ return IndexType((int)i1 + (int)i2); }


и так для всех операций,

можно попробовать создать шаблон:

// прячем операторы в namespace, дабы избежать конфликтов
namespace Typed {

    template<typename T>
    struct type_trait {
        typedef int base_type;
    };

    // маленький трюк, частично защитимся от встроенного преобразования enum --> int
    template<typename T>
    struct type_holder {
        T value;
        type_holder(const T& value_) : value(value_) {}
        operator T() { return value; }

    private:
        operator int();
    };

    // тут все операторы:

    template <typename T> type_holder<T> operator + (T i1, T i2) { 
        typedef typename type_trait<T>::base_type base_type;
        return T(base_type(i1) + base_type(i2)); 
    }

    template <typename T> type_holder<T> operator - (T i1, T i2) { 
        typedef typename type_trait<T>::base_type base_type;
        return T(base_type(i1) - base_type(i2)); 
    }

    template <typename T> T& operator += (T& i1, T i2) { 
        typedef typename type_trait<T>::base_type base_type;
        return (T&)((base_type&)(i1) += base_type(i2)); 
    }

    // аналогично для тонны других операторов...

}


теперь используем:

namespace Typed {  
    enum IndexType {};
}

int main(int argc, _TCHAR* argv[]) {
    using namespace Typed;

    IndexType it1 = IndexType(1), it2=IndexType(2);
    int i1 = 1, i2 =2;

    IndexType it3 = it1 + it2;
    it3 += it1;

    // fail
    int i4 = it1 + it2;

    // fail
    unsigned u1 = it1 + it2;
    
    // fail, пусть все методы и ф-ии возвращают type_holder<T>
    // в этом случае мы сможем присвоить результат T но не int
    int i5 = type_holder<IndexType>(it1);

    return 0;
}
Re[5]: Жёсткая типизация
От: Chez Россия  
Дата: 21.10.04 14:03
Оценка:
Здравствуйте, ssm, Вы писали:

friend bool operator<=(const value_type& lhs, const IDType<T>& rhs) { return !(lhs > rhs.fIDInt); }



Это как ?
Реализация friend внутри класса?
Chez, ICQ# 161095094
Re[6]: Жёсткая типизация
От: ssm Россия  
Дата: 21.10.04 14:25
Оценка:
Здравствуйте, Chez, Вы писали:


C> Это как ?

C> Реализация friend внутри класса?

да
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.