Подтвердить что ты не робот

Как бы вы определили простой метод "min" в obj-c

Я хочу определить методы min и max в классе Utils.

@interface Utils

int min(int a, int b);
int max(int a, int b);

@end

Но я не хочу иметь именованные параметры. Это было бы слишком тяжелое обозначение. Я хотел использовать определение стиля С. Но тогда [Utils min(a, b)] как вызов не работает. В чем моя проблема?

Заранее благодарим за помощь

4b9b3361

Ответ 1

Поскольку вы не используете реализацию OS X objective-c, у вас может не быть доступа к предопределенным макросам MIN и MAX.

Вы можете определить их самостоятельно как

#define MIN(a,b)    ((a) < (b) ? (a) : (b))
#define MAX(a,b)    ((a) > (b) ? (a) : (b))

Вероятно, есть лучший способ определить их, но они создадут простые макросы для вашего использования. Вы можете добавить их в любой общий файл .h, который обычно использует ваш класс.

Ответ 2

Он уже определен как макрос.

MIN(a, b)

MAX(a, b)

Вам не нужно переопределять эти.

Ответ 3

Существует серьезная проблема с решением, опубликованным Брэндоном Боднаром (который на момент написания этой статьи был отмечен как действительное решение).

Проблема описана здесь: http://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Min-and-Max.html И (действительное и безопасное) решение этой проблемы: http://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Typeof.html

Проверьте это сами:

#include <stdio.h>

#define NAIVE_MAX(a,b) (a > b ? a : b)

#define NAIVE_MIN(a,b) (a < b ? a : b)

#if !defined MAX
#define MAX(a,b) \
({ __typeof__ (a) __a = (a); \
__typeof__ (b) __b = (b); \
__a > __b ? __a : __b; })
#endif

#if !defined MIN
#define MIN(a,b) \
({ __typeof__ (a) __a = (a); \
__typeof__ (b) __b = (b); \
__a < __b ? __a : __b; })
#endif

int main (int argc, const char * argv[]) {
    int a = 3;
    int b = 5;

#pragma mark NON-FATAL CASES:
    printf("NAIVE_MAX(%d, %d) => %d\n", a, b, NAIVE_MAX(a, b));
    printf("NAIVE_MIN(%d, %d) => %d\n", a, b, NAIVE_MIN(a, b));

    printf("MAX(%d, %d) => %d\n", a, b, MAX(a, b));
    printf("MIN(%d, %d) => %d\n", a, b, MIN(a, b));

    printf("\nEverything fine so far...\n\n");

#pragma mark FATAL CASES:
    //cache:
    int _a = a;
    int _b = b;
    printf("NAIVE_MAX(%d++, %d++) => %d\n", _a, _b, NAIVE_MAX(a++, b++));

    //reset:
    a = _a;
    b = _b;
    printf("NAIVE_MIN(%d++, %d++) => %d\n", _a, _b, NAIVE_MIN(a++, b++));

    //reset:
    a = _a;
    b = _b;
    printf("NAIVE_MAX(++%d, ++%d) => %d\n", _a, _b, NAIVE_MAX(++a, ++b));

    //reset:
    a = _a;
    b = _b;
    printf("NAIVE_MIN(++%d, ++%d) => %d\n", _a, _b, NAIVE_MIN(++a, ++b));

    printf("\nOuch, this does not look right at all!\n\n");

#pragma mark NON-FATAL CASES:
    //reset:
    a = _a;
    b = _b;
    printf("MAX(%d++, %d++) => %d\n", _a, _b, MAX(a++, b++));

    //reset:
    a = _a;
    b = _b;
    printf("MIN(%d++, %d++) => %d\n", _a, _b, MIN(a++, b++));

    //reset:
    a = _a;
    b = _b;
    printf("MAX(++%d, ++%d) => %d\n", _a, _b, MAX(++a, ++b));

    //reset:
    a = _a;
    b = _b;
    printf("MIN(++%d, ++%d) => %d\n", _a, _b, MIN(++a, ++b));

    printf("\nAh, much better now.\n\n");

    return 0;
}

Журнал консоли:

NAIVE_MAX(3, 5) => 5
NAIVE_MIN(3, 5) => 3
MAX(3, 5) => 5
MIN(3, 5) => 3

Everything fine so far...

NAIVE_MAX(3++, 5++) => 6
NAIVE_MIN(3++, 5++) => 4
NAIVE_MAX(++3, ++5) => 7
NAIVE_MIN(++3, ++5) => 5

Ouch, this does not look right at all!

MAX(3++, 5++) => 5
MIN(3++, 5++) => 3
MAX(++3, ++5) => 6
MIN(++3, ++5) => 4

Ah, much better now.

Так что никогда не используйте наивную реализацию, как видно из кода выше (и, как предлагает Брэндон Боднар, извините, приятель;)), если вы хотите избежать наихудших случаев, подобных этим.

Ответ 4

Это, вероятно, не очень хорошая идея для этого конкретного приложения, но можно написать методы Objective-C с параметрами "без имен" или, скорее, с нулевыми именами:

+ min:(int)a :(int)b;
...
[Utils min:a :b]

(Селектор будет @selector(min::).)

Ответ 5

Objective-C методы класса используют именованные параметры, период. Это так, как есть.

Почему бы не сделать глобальную свободную функцию? Вам не нужен класс Utils для такого рода вещей.

Если вы не хотите загромождать глобальное пространство имен, вы можете использовать Objective-C ++ (переименовать все .m файлы в .mm) и поместить его в пространство имен.

Ответ 6

В файле шаблона с именем "XXIntegerMath.h" отпустите это...

#import <Foundation/Foundation.h>

static inline NSInteger imax(NSInteger a, NSInteger b) {
    return  a > b ? a : b;
}

static inline NSInteger imin(NSInteger a, NSInteger b) {
    return  a < b ? a : b;
}

Затем в вашем классе objective-c...

#import "XXIntegerMath.h"
NSInteger minValue = imin(someValue, someOtherValue);

Он не страдает от проблем, описанных Regexident.