Re: Непонятки с #define min()
От: SchweinDeBurg Россия https://zarezky.spb.ru/
Дата: 13.04.07 10:21
Оценка: 4 (4) +1
Здравствуйте, Чили, Вы писали:

Ч>Как же мне быть если виндовая min, применительно к myClass, меня не устраивает?


Написать перед включением <windows.h>

#define NOMINMAX
- Искренне ваш, Поросенок Пафнутий
Re: Непонятки с #define min()
От: Bell Россия  
Дата: 13.04.07 10:59
Оценка: 2 (1) +1
Здравствуйте, Чили, Вы писали:

Ч>Интересно мне стало, почему я не могу сделать следущее:

Ч>
template<typename T> class myClass {...};
Ч>template<typename T> myClass& min(const myClass &v1, const myClass &v1) {...}

Ч>Так вот, если включаешь <windows.h>, компилятор ругается на объявление ф-ии min.
Ч>Я так понимаю из-за того что в <windef.h> описан #define min().
Ч>Как же мне быть если виндовая min, применительно к myClass, меня не устраивает?

Заключи имя функции в скобки — препроцессор в этом случае не будет выполнять подстановку:


myClass<int> i1, i2;
const myClass<int>& i3 = (min)(i1, i2);
Любите книгу — источник знаний (с) М.Горький
Re[2]: Непонятки с #define min()
От: Roman Odaisky Украина  
Дата: 13.04.07 13:48
Оценка: +2
Здравствуйте, Bell, Вы писали:

B>Заключи имя функции в скобки — препроцессор в этом случае не будет выполнять подстановку:


B>
B>myClass<int> i1, i2;
B>const myClass<int>& i3 = (min)(i1, i2);
B>


Для полноты добавлю, что кроме препроцессора, это отразится и на собственно компиляторе: взятие имени функции в скобки отключает ADL.

Кстати, зачем вообще могут понадобиться Windows::min/max? Они и неустойчивы (min(a, b) дает b при a == b), и опасны (min(i++, j--)), и требуют наличия operator > для max (std::max использует <), и захламляют все namespace, и компаратор не умеют (std::min(a, b, Compare())).

std::min/max тоже имеют проблемы, но они, как мне кажется, на порядок менее опасны: не работает max(x, y) %= min(x, y), зато работает &std::min(0, 1).
До последнего не верил в пирамиду Лебедева.
Re[4]: max(x, y) %= min(x, y)
От: rg45 СССР  
Дата: 13.04.07 14:13
Оценка: 6 (1)
Здравствуйте, Roman Odaisky, Вы писали:

RO>Еще по поводу min/max.


RO>Алгоритм Евклида можно записать так:

RO>
RO>unsigned gcd(unsigned x, unsigned y)
RO>{
RO>    while(x && y)
RO>    {
RO>        max(x, y) %= min(x, y);
RO>    }

RO>    return x + y;
RO>}
RO>

RO>Решил попробовать, осилят ли компиляторы заменить сей код эквивалентным, более эффективным и менее кратким:
RO>
RO>unsigned gcd(unsigned x, unsigned y)
RO>{
RO>    while(x && y)
RO>    {
RO>        if(x < y)
RO>        {
RO>            y %= x;
RO>        }
RO>        else
RO>        {
RO>            x %= y;
RO>        }
RO>    }

RO>    return x + y;
RO>}
RO>


Прошу прощения за оффтопик, но все же... При вычислении наибольшего общего делителя легко можно избежать лишних сравнений внутри цикла:
template<typename T> 
inline T gcd(T a, T b)
{
  while(b)
  {
    T t = b;
    b   = a % b;
    a   = t;
  }
  return a;
}
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
--
Справедливость выше закона. А человечность выше справедливости.
Re[5]: max(x, y) %= min(x, y)
От: Roman Odaisky Украина  
Дата: 13.04.07 14:38
Оценка: 1 (1)
Здравствуйте, rg45, Вы писали:

R>Прошу прощения за оффтопик, но все же... При вычислении наибольшего общего делителя легко можно избежать лишних сравнений внутри цикла:

R>
R>template<typename T> 
R>inline T gcd(T a, T b)
R>{
R>  while(b)
R>  {
R>    T t = b;
R>    b   = a % b;
R>    a   = t;
R>  }
R>  return a;
R>}
R>


Хм. Заинтересовавшись, полез в boost/math/common_factor_rt.hpp:
while ( true )
{
    if ( a == zero )
        return b;
    b %= a;

    if ( b == zero )
        return a;
    a %= b;
}
До последнего не верил в пирамиду Лебедева.
Непонятки с #define min()
От: Чили Россия  
Дата: 13.04.07 10:20
Оценка:
Интересно мне стало, почему я не могу сделать следущее:
template<typename T> class myClass {...};
template<typename T> myClass& min(const myClass &v1, const myClass &v1) {...}

Так вот, если включаешь <windows.h>, компилятор ругается на объявление ф-ии min.
Я так понимаю из-за того что в <windef.h> описан #define min().
Как же мне быть если виндовая min, применительно к myClass, меня не устраивает?
Re: Непонятки с #define min()
От: g_i  
Дата: 13.04.07 10:21
Оценка:
Здравствуйте, Чили, Вы писали:

Ч>Интересно мне стало, почему я не могу сделать следущее:

Ч>
template<typename T> class myClass {...};
Ч>template<typename T> myClass& min(const myClass &v1, const myClass &v1) {...}

Ч>Так вот, если включаешь <windows.h>, компилятор ругается на объявление ф-ии min.
Ч>Я так понимаю из-за того что в <windef.h> описан #define min().
Ч>Как же мне быть если виндовая min, применительно к myClass, меня не устраивает?

#undef min
Re[2]: Непонятки с #define min()
От: Аноним  
Дата: 13.04.07 10:38
Оценка:
Здравствуйте, g_i, Вы писали:

g_i>#undef min

#undef min
меня не устраивает!
Нужно выполнить как бы перекрытие функций (хотя windows::min это не функция)
Т.е. чтобы для любых типов вызывалась windows::min, а для типа myClass — моя min!
Re[3]: Непонятки с #define min()
От: SchweinDeBurg Россия https://zarezky.spb.ru/
Дата: 13.04.07 10:41
Оценка:
Здравствуйте, Аноним, Вы писали:

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


А>Т.е. чтобы для любых типов вызывалась windows::min, а для типа myClass — моя min!


using std::min;
using std::max;

даст практически такой же эффект.
- Искренне ваш, Поросенок Пафнутий
Re[3]: max(x, y) %= min(x, y)
От: Roman Odaisky Украина  
Дата: 13.04.07 14:03
Оценка:
Еще по поводу min/max.

Алгоритм Евклида можно записать так:
unsigned gcd(unsigned x, unsigned y)
{
    while(x && y)
    {
        max(x, y) %= min(x, y);
    }

    return x + y;
}

Решил попробовать, осилят ли компиляторы заменить сей код эквивалентным, более эффективным и менее кратким:
unsigned gcd(unsigned x, unsigned y)
{
    while(x && y)
    {
        if(x < y)
        {
            y %= x;
        }
        else
        {
            x %= y;
        }
    }

    return x + y;
}

Не осилили, ни VC8, ни MinGW 3.4.2.
Особенно смешно выглядит вариант g++:
    cmpl    %eax, %ecx
    jl    L4
    movl    %edi, %ebx
L4:
    cmpl    %eax, %ecx
До последнего не верил в пирамиду Лебедева.
Re[5]: max(x, y) %= min(x, y)
От: rg45 СССР  
Дата: 13.04.07 14:19
Оценка:
Здравствуйте, rg45, Вы писали:

R>Прошу прощения за оффтопик, но все же... При вычислении наибольшего общего делителя легко можно избежать лишних сравнений внутри цикла:

R>
R>template<typename T> 
R>inline T gcd(T a, T b)
R>{
R>  while(b)
R>  {
R>    T t = b;
R>    b   = a % b;
R>    a   = t;
R>  }
R>  return a;
R>}
R>


Результат функции от последовательности аргументов не зависит.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
--
Справедливость выше закона. А человечность выше справедливости.
Re[6]: max(x, y) %= min(x, y)
От: rg45 СССР  
Дата: 13.04.07 14:42
Оценка:
Здравствуйте, Roman Odaisky, Вы писали:

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


RO>Хм. Заинтересовавшись, полез в boost/math/common_factor_rt.hpp:

RO>
RO>while ( true )
RO>{
RO>    if ( a == zero )
RO>        return b;
RO>    b %= a;

RO>    if ( b == zero )
RO>        return a;
RO>    a %= b;
RO>}
RO>


ИМХО, налицо преждевременная пессимизация
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
--
Справедливость выше закона. А человечность выше справедливости.
Re[6]: max(x, y) %= min(x, y)
От: _KAV_  
Дата: 13.04.07 16:42
Оценка:
Ну, а если писать очень кратко, то НОД можно найти так:
int GCD( int a, int b )
{
while( a*b ) a > b ? a %= b : b %= a;
return a+b;
}
Re[7]: max(x, y) %= min(x, y)
От: Roman Odaisky Украина  
Дата: 14.04.07 11:26
Оценка:
Здравствуйте, _KAV_, Вы писали:

_KA>Ну, а если писать очень кратко, то НОД можно найти так:

_KA>int GCD( int a, int b )
_KA>{
_KA> while( a*b ) a > b ? a %= b : b %= a;
_KA> return a+b;
_KA>}

Ну, это уже было: http://rsdn.ru/Forum/Message.aspx?mid=2447449&amp;only=1
Автор: Roman Odaisky
Дата: 13.04.07
.

А в while всё же лучше a && b. А то GCD(65536, 65536) будет работать очень интересно.
До последнего не верил в пирамиду Лебедева.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.