Разница между определением friend-функциями фтеле/вовне.
От: _Winnie Россия C++.freerun
Дата: 02.10.05 17:13
Оценка:
Скажите, почему так не компилируется,
#ifdef NDEBUG

typedef bool safe_bool_t;

const safe_bool_t safe_true = 1;
const safe_bool_t safe_false = 0;

#else

struct safe_bool_gen_t
{
    void f() {};
};

typedef void (safe_bool_gen_t::*safe_bool_t)();

const safe_bool_t safe_true = &safe_bool_gen_t::f;
const safe_bool_t safe_false = 0;

#endif




template <class T>
struct my_ptr_t
{
    T *m_p;

    my_ptr_t(T *in_p)
        :m_p(in_p)
    {
    }

    operator safe_bool_t()
    {
        return m_p ? safe_true : safe_false;
    }

    friend bool operator==(const my_ptr_t<T> &l, const my_ptr_t<T> &r)
    {
        return l.m_p == r.m_p;
    }
};


int main()
{
    my_ptr_t<int> op = new int;

    if (op == NULL)
    {
    }
}


GCC:
test4.cpp: In function `int main()':
test4.cpp:24: error: ambiguous overload for 'operator==' in 'op == 0'
test4.cpp:24: note: candidates are: operator==(int, int) <built-in>
test4.cpp:15: note:                 bool operator==(const my_ptr_t<int>&, const my_ptr_t<int>&)

MSVC:
test4.cpp(24) : error C2666: 'my_ptr_t<T>::operator`=='' : 2 overloads have similar conversions
        with
        [
            T=int
        ]
        test4.cpp(14): could be 'bool my_ptr_t<T>::operator ==(const my_ptr_t<T> &,const my_ptr_t<T> &)' [found using argument-dependent lookup]
        with
        [
            T=int
        ]
        or       'built-in C++ operator==(bool, int)'
        while trying to match the argument list '(my_ptr_t<T>, int)'
        with
        [
            T=int
        ]

IC++:

.\test4.cpp(24): error: more than one operator "==" matches these operands:
            built-in operator "arithmetic == arithmetic"
            function "operator==(const my_ptr_t<int> &, const my_ptr_t<int> &)"
            operand types are: my_ptr_t<int> == int
      if (op == 0)


а так компилируется:


template <class T>
struct my_ptr_t
{
    T *m_p;

    my_ptr_t(T *in_p)
        :m_p(in_p)
    {
    }

    operator safe_bool_t()
    {
        return m_p ? safe_true : safe_false;
    }

    template <class U>
    friend bool operator==(const my_ptr_t<U> &l, const my_ptr_t<U> &r);
};


template <class T>
bool operator==(const my_ptr_t<T> &l, const my_ptr_t<T> &r)
{
    return l.m_p == r.m_p;
}

int main()
{
    my_ptr_t<int> op = new int;

    if (op == NULL)
    {
    }
}


Могу ли я быть уверен на 100%, что при сравнении p == NULL всегда будет вызываться
p.operator bool() == NULL,
а не
p == my_ptr<int>(NULL)
?
Правильно работающая программа — просто частный случай Undefined Behavior
Re: Разница между определением friend-функциями фтеле/вовне.
От: Павел Кузнецов  
Дата: 02.10.05 17:26
Оценка: 6 (1)
_Winnie,

> Скажите, почему так не компилируется,

> <...>
>
> template <class T>
> struct my_ptr_t
> {
>     my_ptr_t(T *in_p)
>
>     operator safe_bool_t()
>
>     friend bool operator==(const my_ptr_t<T> &l, const my_ptr_t<T> &r)
> };
>
>     my_ptr_t<int> op = new int;
>     if (op == NULL)
>


Есть два варианта трактовки выделенного выражения:
1) op == my_ptr_t<int>(NULL)
2) op.operator safe_bool_t() == NULL

Соответственно, компиляторы ругаются по поводу неоднозначности.

> а так компилируется:

>
> template <class T>
> struct my_ptr_t
> {
>     my_ptr_t(T *in_p)
>
>     operator safe_bool_t()
>
>     template <class U>
>     friend bool operator==(const my_ptr_t<U> &l, const my_ptr_t<U> &r);
> };
>
>     my_ptr_t<int> op = new int;
>     if (op == NULL)
>


А теперь эта неоднзначность разрешается в пользу op.operator safe_bool_t() == NULL, т.к. теперь operator == должен быть инстанцирован из шаблона, а "обычная" функция при прочих равных у шаблона "выигрывает".

> Могу ли я быть уверен на 100%, что при сравнении p == NULL всегда будет вызываться

> p.operator bool() == NULL,
> а не
> p == my_ptr<int>(NULL)
> ?

В данном случае -- да.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[2]: Разница между определением friend-функциями фтеле/вов
От: _Winnie Россия C++.freerun
Дата: 02.10.05 18:27
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>_Winnie,


>> Скажите, почему так не компилируется,

>> <...>
>>
>> template <class T>
>> struct my_ptr_t
>> {
>>     my_ptr_t(T *in_p)
>>
>>     operator safe_bool_t()
>>
>>     friend bool operator==(const my_ptr_t<T> &l, const my_ptr_t<T> &r)
>> };

>>     if (op == NULL)
>>


ПК>Есть два варианта трактовки выделенного выражения:

ПК>1) op == my_ptr_t<int>(NULL)
ПК>2) op.operator safe_bool_t() == NULL

ПК>Соответственно, компиляторы ругаются по поводу неоднозначности.


>> а так компилируется:

>>
>> template <class T>
>> struct my_ptr_t
>> {
>>     my_ptr_t(T *in_p)
>>
>>     operator safe_bool_t()
>>
>>     template <class U>
>>     friend bool operator==(const my_ptr_t<U> &l, const my_ptr_t<U> &r);
>> };
>>
>>     my_ptr_t<int> op = new int;
>>     if (op == NULL)
>>


ПК>А теперь эта неоднзначность разрешается в пользу op.operator safe_bool_t() == NULL, т.к. теперь operator == должен быть инстанцирован из шаблона, а "обычная" функция при прочих равных у шаблона "выигрывает".


Не понял. Ведь во втором компилирующемся случае operator safe_bool_t — тоже шаблон(member функция шаблона => тоже шаблонная функция), а в первом случае вроде бы та же ситуция — operator == — тоже шаблон.
Правильно работающая программа — просто частный случай Undefined Behavior
Re[3]: Разница между определением friend-функциями фтеле/вов
От: __LP  
Дата: 02.10.05 18:33
Оценка:
Здравствуйте, _Winnie, Вы писали:

_W>Не понял. Ведь во втором компилирующемся случае operator safe_bool_t — тоже шаблон(member функция шаблона => тоже шаблонная функция), а в первом случае вроде бы та же ситуция — operator == — тоже шаблон.


Друзья не являются мемберами и соответственно шаблонами, если конечно они явно так не определены.
C++ можно выучить за 21 день! ...если дни — полярные.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.