вот решил попробовать написать простенький класс и ничего толком не получается.
идея такая — мне нужен простой тип с его поведением плюс еще одно свойство...
первое что пришло в голову — наследование (точнее это было второе, но с первым я совсем запутался...)
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())...
Здравствуйте, 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;
};
Здравствуйте, 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) А. Эйнштейн
1. (const T &other) — это значит что мы сравниваем с T? тогда у него нет ф-ции is_null. Наверное всетаки (const nullable<T> &other)
2. я так понял, что this имеет тип указатель на nullable<T>. тогда может так: this->is_null ?
3. по-моему тут явная опечатка, но я не могу все равно написать эту строку...
я сделал ф-цию value, которая возвращает const T &.
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>
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
все, вопрос снимается!
поискал на форуме — нашел ответ! причем там было предложение топик удалить!!!
эх, не зря я историю в аське храню — иногда и там что-то полезное найти можно...