наследование или...
От: Oleg A. Bachin Украина  
Дата: 09.08.04 12:14
Оценка:
Добрый день всем...

просьба не пинать сильно — только учусь...

вот решил попробовать написать простенький класс и ничего толком не получается.
идея такая — мне нужен простой тип с его поведением плюс еще одно свойство...

первое что пришло в голову — наследование (точнее это было второе, но с первым я совсем запутался...)

template <typename T>
class nullable: public T
{
  public:

    nullable(): is_null_(true) {};
    nullable(const T &other): is_null_(false), T(other) {};

    bool & is_null() const 
    {
      return is_null_;
    };

    bool operator == (const T &other) const
    {
      if (this.is_null || other.is_null) 
        throw null_value_compare("null_value_compare");
      // 1. проверка типов

      // 2. что возвращать?
    };
  private:
    bool is_null_;
};

int main() 
{
  nullable<std::string> str = "std::string";
  std::cout << str.c_str() << std::endl;
}


отступление: за все лишние '&' и 'const' давайте сразу по рукам — еще не чувствую...

1. проверка типов я так понимаю это compile-time, но как здесь избежать авто-преобразования?
2. как вызвать оператор сравнения базового класса? явным преобразованием? static_cast?

больше всего пугает здесь наследование от простого типа, так что этот вариант наверное отпадает...

теперь первое, что пришло в голову — имплементация, но с ней еще хуже.
не могу понять, как добиться поведения, такого же как простой тип?
конечно, можно завести ф-цию, которая будет возвращать ссылку на T, но хотелось бы более дружественного поведения.
можно перегрузить оператор '()', но тогда прийдется делать преобразования (т.е. выглядеть будет так: std::string(str).c_str())...
Best regards,
Oleg A. Bachin
Re: наследование или...
От: Glоbus Украина  
Дата: 09.08.04 12:20
Оценка:
Здравствуйте, Oleg A. Bachin, Вы писали:

Удалено избыточное цитирование — WH

OAB>больше всего пугает здесь наследование от простого типа, так что этот вариант наверное отпадает...


Хм.... наверное еще должно пугать отсутсвие у класса T контрсуктора по умолчанию и приватные конструкторы/деструкторы
Удачи тебе, браток!
Re[2]: наследование или...
От: Oleg A. Bachin Украина  
Дата: 09.08.04 12:26
Оценка:
Здравствуйте, Glоbus, Вы писали:

OAB>>    bool operator == (const T &other) const
OAB>>    {
OAB>>      if (this.is_null || other.is_null) 
OAB>>        throw null_value_compare("null_value_compare");
OAB>>      // 1. проверка типов

OAB>>      // 2. что возвращать?
G>          [/b]return *this = _other; //может так[/b]
OAB>>    };
OAB>>


не похоже... скорее
  return T(this) == other;

но я не уверен на сколько это корректно...


G>Хм.... наверное еще должно пугать отсутсвие у класса T контрсуктора по умолчанию и приватные конструкторы/деструкторы


повторюсь, планируется использовать с простыми типами. так что эти ограничения оставим.
Best regards,
Oleg A. Bachin
Re: наследование или...
От: Oleg A. Bachin Украина  
Дата: 09.08.04 12:35
Оценка:
ой нет...
первый вариант похоже совсем никакой...
Best regards,
Oleg A. Bachin
Re: наследование или...
От: WolfHound  
Дата: 09.08.04 12:59
Оценка:
Здравствуйте, Oleg A. Bachin, Вы писали:
//Заглушка чтобы компилятор не орал.
struct null_value_compare
{
    template<class T>
    null_value_compare(T const&)
    {}
};
template <typename T>
struct nullable
{
    typedef T                    value_type;
    typedef value_type*            pointer;
    typedef value_type&            reference;
    typedef value_type const*    const_pointer;
    typedef value_type const&    const_reference;
    nullable()
        : is_null_(true) 
    {}//; после функций не надо.
    nullable(const_reference other)
        : is_null_(false)
        , value_(other) 
    {}

    bool is_null() const //возвращат ссылку не надо bool легкий тип. 
        //Болие того оно даже не скомпилится ибо возвращать не константную ссылку на поле объекта из константного метода...
    {
        return is_null_;
    }

    friend bool operator==(nullable const& lhs, nullable const& rhs)
    {
        if (lhs.is_null() || rhs.is_null()) //функции надо вызывать :))
            throw null_value_compare("null_value_compare");
        return lhs.value_==rhs.value_;
    }

    pointer operator->()
    {
        return &value_;
    }
    const_pointer operator->()const
    {
        return &value_;
    }
private:
    value_type value_;
    bool is_null_;
};

int main() 
{
    try
    {
        nullable<std::string> str1 = "std::string";
        nullable<std::string> str2 = "asd";
        nullable<std::string> str3;
        std::cout << str1->c_str() << std::endl;
        std::cout << (str1==str1) << std::endl;
        std::cout << (str1==str2) << std::endl;
        std::cout << (str2==str2) << std::endl;
        std::cout << (str1==str3) << std::endl;
    }
    catch(...)
    {
        std::cout<<"oops\n";
    }
}
... << RSDN@Home 1.1.3 beta 1 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[2]: наследование или...
От: Oleg A. Bachin Украина  
Дата: 09.08.04 13:30
Оценка:
Здравствуйте, WolfHound, Вы писали:

в эту сторону сейчас и копаю... осталось еще несколько белых пятен.
1. nullable<int> — всетаки нужна ф-ция value() ?

2.

WH>template <typename T>

WH>struct nullable
WH>{
// а здесь не нужно?
friend bool operator==(nullable<T> const& lhs, nullable<T> const& rhs)

WH> friend bool operator==(nullable const& lhs, nullable const& rhs)

WH> {
WH> if (lhs.is_null() || rhs.is_null()) //функции надо вызывать
WH> throw null_value_compare("null_value_compare");
WH> return lhs.value_==rhs.value_; // 3*
WH> }
WH>};

3. не собирается .пишет что

error C3767: '==' matching function is not accessible

Best regards,
Oleg A. Bachin
Re[3]: наследование или...
От: Glоbus Украина  
Дата: 09.08.04 14:39
Оценка:
Здравствуйте, Oleg A. Bachin, Вы писали:

OAB>Здравствуйте, Glоbus, Вы писали:


OAB>
OAB>>>    bool operator == (const T &other) const
OAB>>>    {
OAB>>>      if (this.is_null || other.is_null) 
OAB>>>        throw null_value_compare("null_value_compare");
OAB>>>      // 1. проверка типов

OAB>>>      // 2. что возвращать?
G>>          [/b]return *this = _other; //может так[/b]
OAB>>>    };
OAB>>>


OAB>не похоже... скорее

OAB>
OAB>  return T(this) == other;
OAB>

OAB>но я не уверен на сколько это корректно...

Не корректо. Ты указатель приводишь к типу Т (например к double).Чтобы получить занчение будь добр запиши тогда уж *this — или я чего-то не понимаю?


G>>Хм.... наверное еще должно пугать отсутсвие у класса T контрсуктора по умолчанию и приватные конструкторы/деструкторы


OAB>повторюсь, планируется использовать с простыми типами. так что эти ограничения оставим.


Может тогда можно не наследованием, а включением организовать все это
Типа

template <typename T>
class nullable
{
public:

    nullable(): is_null_(true) {};
    nullable(const T &other): is_null_(false), m_Value(other) {};

    bool & is_null() const 
    {
        return is_null_;
    }

    bool operator == (const T &other) const
    {
        if (this.is_null || other.is_null) 
            throw std::logic_error("null_value_compare");
        return m_Value == T

    }

    operator T ()
    {
        return m_Value;
    }
private:
    bool is_null_;
    T m_Value;
};
Удачи тебе, браток!
Re[3]: наследование или...
От: WolfHound  
Дата: 09.08.04 14:44
Оценка:
Здравствуйте, Oleg A. Bachin, Вы писали:

OAB>1. nullable<int> — всетаки нужна ф-ция value() ?

Похоже что да.
OAB> // а здесь не нужно?
Нет

OAB>3. не собирается .пишет что

OAB>

OAB>error C3767: '==' matching function is not accessible

Какой компилятор? На VC++7.1 все работает.
... << RSDN@Home 1.1.3 beta 1 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[4]: наследование или...
От: Oleg A. Bachin Украина  
Дата: 09.08.04 14:55
Оценка:
Здравствуйте, Glоbus, Вы писали:

повторюсь, я только учусь...

можно вот здесь уточнить?

G>
G>template <typename T>
G>class nullable
G>{
G>public:

G>    bool operator == (const T &other) const // 1*
G>    {
G>        if (this.is_null || other.is_null) // 2*
G>            throw std::logic_error("null_value_compare");
G>        return m_Value == T // 3*
G>    }
G>


1. (const T &other) — это значит что мы сравниваем с T? тогда у него нет ф-ции is_null. Наверное всетаки (const nullable<T> &other)

2. я так понял, что this имеет тип указатель на nullable<T>. тогда может так: this->is_null ?
3. по-моему тут явная опечатка, но я не могу все равно написать эту строку...

я сделал ф-цию value, которая возвращает const T &.
 const T & value() const
    {
        return value_;
    }

и пытаюсь написать вот так:
    template <typename T>
    bool operator==(nullable<T> const& other)
    {
        if (this->is_null() || other.is_null()) 
            throw null_value_compare("null_value_compare");
        return (this->value_ == other.value());
    }


на что получаю:

error C3767: '==' matching function is not accessible

Best regards,
Oleg A. Bachin
от модератора
От: WolfHound  
Дата: 09.08.04 15:09
Оценка:
Здравствуйте, Glоbus, Вы злостно оверквотели:

Оверквотинг запрещен правилами сайта. К томуже это просто не уважение к другим участникам форума. Еще раз и...
... << RSDN@Home 1.1.3 beta 1 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[4]: наследование или...
От: Oleg A. Bachin Украина  
Дата: 09.08.04 15:10
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Какой компилятор? На VC++7.1 все работает.


именно он!

cl /EHsc /TP test.cpp
Best regards,
Oleg A. Bachin
Re[2]: наследование или...
От: v0id  
Дата: 10.08.04 06:28
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, Oleg A. Bachin, Вы писали:

WH>
WH>//Заглушка чтобы компилятор не орал.
WH>struct null_value_compare
WH>{
WH>    template<class T>
WH>    null_value_compare(T const&)
WH>    {}
WH>};
//...
WH>

struct null_value_compare надо делать вложенным на мой взгляд, если она необходима только для генерации исключения...
Re[5]: наследование или...
От: Glоbus Украина  
Дата: 10.08.04 10:08
Оценка:
Здравствуйте, Oleg A. Bachin, Вы писали:

OAB>Здравствуйте, Glоbus, Вы писали:


OAB>повторюсь, я только учусь...


OAB>можно вот здесь уточнить?


G>>
G>>template <typename T>
G>>class nullable
G>>{
G>>public:

G>>    bool operator == (const T &other) const // 1*
G>>    {
G>>        if (this.is_null || other.is_null) // 2*
G>>            throw std::logic_error("null_value_compare");
G>>        return m_Value == T // 3*
G>>    }
G>>


OAB>1. (const T &other) — это значит что мы сравниваем с T? тогда у него нет ф-ции is_null. Наверное всетаки (const nullable<T> &other)


OAB>2. я так понял, что this имеет тип указатель на nullable<T>. тогда может так: this->is_null ?

OAB>3. по-моему тут явная опечатка, но я не могу все равно написать эту строку...

OAB>я сделал ф-цию value, которая возвращает const T &.

OAB>
OAB> const T & value() const
OAB>    {
OAB>        return value_;
OAB>    }
OAB>

OAB>и пытаюсь написать вот так:
OAB>
OAB>    template <typename T>
OAB>    bool operator==(nullable<T> const& other)
OAB>    {
OAB>        if (this->is_null() || other.is_null()) 
OAB>            throw null_value_compare("null_value_compare");
OAB>        return (this->value_ == other.value());
OAB>    }
OAB>


OAB>на что получаю:

OAB>

OAB>error C3767: '==' matching function is not accessible


Да, пардон, должно было быть так

template <typename T>
class nullable
{
public:

    nullable(): is_null_(true) {};
    nullable(const T &other): is_null_(false), m_Value(other) {};

    bool & is_null() const 
    {
        return is_null_;
    }

    bool operator == ( const nullable<T>& _other )
    {
        if (this->is_null_ || _other.is_null_) 
            throw std::logic_error("null_value_compare");
        return m_Value == _other.m_Value;

    }
    
    operator T ()
    {
        return m_Value;
    }
private:
    bool is_null_;
    T m_Value;
};






int main()
{
//использование
    nullable<int> obj1(5);
    nullable<int> obj2(5);

    std::cout << (obj1 == obj2) << std::endl;
    std::cout << obj1 << std::endl;
    std::cout << ( obj1 + 5 ) << std::endl;

    

}
Удачи тебе, браток!
Re[6]: наследование или...
От: Oleg A. Bachin Украина  
Дата: 10.08.04 11:55
Оценка:
Здравствуйте, Glоbus, Вы писали:

прошу прощения на все эти непонятки. на самом деле, оказалась проблема в другом:

#include <iostream>
int main()
{
    std::string str1("str1");
    std::string str2("str2");

    std::cout << (str1 == str2) << std::endl;
}


cl /EHsc /TP test2.cpp

test2.cpp
test2.cpp(7) : error C2784: 'bool std::operator ==(const std::allocator<_Ty> &,const std::allocator<_Other> &)' : could not deduce template argument for 'const std::allocator<_Ty> &' from 'std::string'
F:\Microsoft\VS2003\Vc7\include\xmemory(165) : see declaration of 'std::operator`==''
test2.cpp(7) : error C2784: 'bool std::operator ==(const std::allocator<_Ty> &,const std::allocator<_Other> &)' : could not deduce template argument for 'const std::allocator<_Ty> &' from 'std::string'
F:\Microsoft\VS2003\Vc7\include\xmemory(165) : see declaration of 'std::operator`==''
test2.cpp(7) : error C2784: 'bool std::operator ==(const std::allocator<_Ty> &,const std::allocator<_Other> &)' : could not deduce template argument for 'const std::allocator<_Ty> &' from 'std::string'
F:\Microsoft\VS2003\Vc7\include\xmemory(165) : see declaration of 'std::operator`==''
test2.cpp(7) : error C2784: 'bool std::operator ==(const std::istreambuf_iterator<_Elem,_Traits> &,const std::istreambuf_iterator<_Elem,_Traits> &)' : could not deduce template argument for 'const std::istreambuf_iterator<_Elem,_Traits> &' from 'std::string'
F:\Microsoft\VS2003\Vc7\include\xutility(940) : see declaration of 'std::operator`==''
test2.cpp(7) : error C2784: 'bool std::operator ==(const std::istreambuf_iterator<_Elem,_Traits> &,const std::istreambuf_iterator<_Elem,_Traits> &)' : could not deduce template argument for 'const std::istreambuf_iterator<_Elem,_Traits> &' from 'std::string'
F:\Microsoft\VS2003\Vc7\include\xutility(940) : see declaration of 'std::operator`==''
test2.cpp(7) : error C2784: 'bool std::operator ==(const std::istreambuf_iterator<_Elem,_Traits> &,const std::istreambuf_iterator<_Elem,_Traits> &)' : could not deduce template argument for 'const std::istreambuf_iterator<_Elem,_Traits> &' from 'std::string'
F:\Microsoft\VS2003\Vc7\include\xutility(940) : see declaration of 'std::operator`==''
test2.cpp(7) : error C2784: 'bool std::operator ==(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt> &)' : could not deduce template argument for 'const std::reverse_iterator<_RanIt> &' from 'std::string'
F:\Microsoft\VS2003\Vc7\include\xutility(641) : see declaration of 'std::operator`==''
test2.cpp(7) : error C2784: 'bool std::operator ==(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt> &)' : could not deduce template argument for 'const std::reverse_iterator<_RanIt> &' from 'std::string'
F:\Microsoft\VS2003\Vc7\include\xutility(641) : see declaration of 'std::operator`==''
test2.cpp(7) : error C2784: 'bool std::operator ==(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt> &)' : could not deduce template argument for 'const std::reverse_iterator<_RanIt> &' from 'std::string'
F:\Microsoft\VS2003\Vc7\include\xutility(641) : see declaration of 'std::operator`==''
test2.cpp(7) : error C2784: 'bool std::operator ==(const std::pair<_Ty1,_Ty2> &,const std::pair<_Ty1,_Ty2> &)' : could not deduce template argument for 'const std::pair<_Ty1,_Ty2> &' from 'std::string'
F:\Microsoft\VS2003\Vc7\include\utility(57) : see declaration of 'std::operator`==''
test2.cpp(7) : error C2784: 'bool std::operator ==(const std::pair<_Ty1,_Ty2> &,const std::pair<_Ty1,_Ty2> &)' : could not deduce template argument for 'const std::pair<_Ty1,_Ty2> &' from 'std::string'
F:\Microsoft\VS2003\Vc7\include\utility(57) : see declaration of 'std::operator`==''
test2.cpp(7) : error C2784: 'bool std::operator ==(const std::pair<_Ty1,_Ty2> &,const std::pair<_Ty1,_Ty2> &)' : could not deduce template argument for 'const std::pair<_Ty1,_Ty2> &' from 'std::string'
F:\Microsoft\VS2003\Vc7\include\utility(57) : see declaration of 'std::operator`==''
test2.cpp(7) : error C2676: binary '==' : 'std::string' does not define this operator or a conversion to a type acceptable to the predefined operator


тут я сам точно не разберусь...
Best regards,
Oleg A. Bachin
Re[7]: наследование или...
От: Oleg A. Bachin Украина  
Дата: 10.08.04 13:26
Оценка:
все, вопрос снимается!
поискал на форуме — нашел ответ! причем там было предложение топик удалить!!!
эх, не зря я историю в аське храню — иногда и там что-то полезное найти можно...
Best regards,
Oleg A. Bachin
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.