werehuman 29.07.2011 19:10 Psi+

Знакомому при собеседовании в достаточно престижную кампанию задали вопрос: можно ли перегрузить функцию так, чтобы имя и аргументы были одинаковые, а результаты разные. Знакомый резво сказал "нет". Оказалось, это неправильно, но как это сделать не сказали.
Я тут за полчаса додумался как реализовать такую штуку. Может, кто предложит идею лучше моей?

c++
Recommended by: @Kona-chan
1. 0xd34df00d 29.07.2011 19:11 Azoth_primary

const

2. Captain 29.07.2011 19:12 HERP, SWEET DERP

"один мой знакомый" говоришь

3. werehumanCaptain /2 29.07.2011 19:12 Psi+

нет, не я

4. werehuman0xd34df00d /1 29.07.2011 19:12 Psi+

опа, не додумался. Я нагородил костыли

5. 0xd34df00dwerehuman /4 29.07.2011 19:12 Azoth_primary

Покажи.

6. werehuman0xd34df00d /5 29.07.2011 19:13 Psi+

сначала ты

7. 0xd34df00dwerehuman /6 29.07.2011 19:15 Azoth_primary

void f (int, char*);
int f (int, char*) const;

8. Rayslava0xd34df00d /7 29.07.2011 19:16 Workstation

Ок.

9. werehuman0xd34df00d /7 29.07.2011 19:17 Psi+

void test() {
std::cout << "void test" << std::endl;
}

int test() const {
std::cout << "int test" << std::endl;
return 123;
}

test.cpp:21: error: non-member function ‘int test()’ cannot have cv-qualifier
test.cpp: In function ‘int test()’:
test.cpp:21: error: new declaration ‘int test()’
test.cpp:17: error: ambiguates old declaration ‘void test()’
test.cpp: In function ‘int main()’:
test.cpp:32: error: void value not ignored as it ought to be

10. DZhon0xd34df00d /1 29.07.2011 19:18 DZhon-ПК

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

11. DZhonwerehuman /9 29.07.2011 19:19 DZhon-ПК

конст-квалификации доступна только для методов, ебаный стыд

12. werehuman 29.07.2011 19:19 Psi+

мой костыль. Это уже не функции, конечно, но оно работает. http://pastebin.com/NK64D58a
К тому же точной формулировки я не знаю.

13. werehumanDZhon /11 29.07.2011 19:20 Psi+

люблю c++

14. DZhonwerehuman /13 29.07.2011 19:21 DZhon-ПК

Однохуйственно, это надо просто знать :)

15. werehumanDZhon /11 29.07.2011 19:22 Psi+

struct Govno {
void test() {
std::cout << "void test" << std::endl;
}

int test() const {
std::cout << "int test" << std::endl;
return 123;
}
};

...

Govno().test();
a = Govno().test();

test.cpp: In function ‘int main()’:
test.cpp:34: error: void value not ignored as it ought to be

16. DZhonwerehuman /15 29.07.2011 19:23 DZhon-ПК

кастани к консту, неоднозначный вызов же

17. werehumanDZhon /16 29.07.2011 19:24 Psi+

ну-ка покажи как

18. DZhonwerehuman /15 29.07.2011 19:26 DZhon-ПК

static_cast<const Govno>

19. werehumanDZhon /18 29.07.2011 19:26 Psi+

получилось.
Govno().test();
a = static_cast<const Govno>(Govno()).test();

Нахуй так жить?

20. Rayslavawerehuman /19 29.07.2011 19:27 Workstation

Не хочешь грязи — не лезь в плюсы, хуле.

21. werehuman 29.07.2011 19:27 Psi+

есть ещё решения? Ну же, пасаны, вы же профессионалы С++, у вас гонору столько, что вы заставляете меня смущаться, глядя на вас!

22. DZhonwerehuman /19 29.07.2011 19:28 DZhon-ПК

По-моему все логично, хоть и вербозно.

23. werehumanDZhon /22 29.07.2011 19:29 Psi+

теряется смысл перегрузки. Ты просто сделал функцию /* метод */ с новым именем, который помимо исходных символов содержит <>, const и

24. werehumanwerehuman /23 29.07.2011 19:29 Psi+

нутыпонел

25. DZhonwerehuman /24 29.07.2011 19:30 DZhon-ПК

ваще-то ты мог с самого начала создать конст объект и не объебываться с кастом

26. werehumanDZhon /25 29.07.2011 19:31 Psi+

const Govno a; Govno b; std::cout << a.test() << " " << b.test() << std::endl;
Опять же, две разные "функции" с разными названиями: a.test() и b.test()

27. werehumanwerehuman /26 29.07.2011 19:32 Psi+

и неочевидно шопесдец. Проще было сделать Govno<void> a и Govno<int> b

28. DZhonwerehuman /26 29.07.2011 19:32 DZhon-ПК

то, что ты абсолютно разные функции делаешь перегруженными с одним именем — это твои проблемы, вот честно

29. werehumanDZhon /28 29.07.2011 19:32 Psi+

/0

30. werehumanDZhon /28 29.07.2011 19:32 Psi+

нечем отмазаться — не кричи, что умный

31. DZhonwerehuman /30 29.07.2011 19:33 DZhon-ПК

пруфани-ка. А так, во всех книжках по плюсах об этом аспекте пишут, например, Скотт Майерс, 55 советов.

32. werehumanDZhon /31 29.07.2011 19:35 Psi+

учись читать. «Знакомому при собеседовании в достаточно престижную кампанию задали вопрос: можно ли перегрузить функцию так, чтобы имя и аргументы были одинаковые, а результаты разные. Знакомый резво сказал "нет". Оказалось, это неправильно, но как это сделать не сказали.»

33. DZhonwerehuman /32 29.07.2011 19:39 DZhon-ПК

стоп, я просил пруф на "нечем отмазаться — не кричи, что умный". U, в общем.

34. werehumanDZhon /33 29.07.2011 19:40 Psi+

ты мне стал лечить, что моя задача тупая. Я не спрашивал, тупая ли моя задача. Я спрашивал как её решить. А ты, когда зафейлил, стал гнать на мой идиотизм.

35. 0xd34df00dwerehuman /9 29.07.2011 19:47 Azoth_primary

Это для member-функций же.

36. werehuman0xd34df00d /35 29.07.2011 19:48 Psi+

напиши готовый snippet, который вставил и работает

37. 0xd34df00dwerehuman /13 29.07.2011 19:48 Azoth_primary

Это же очевидно.

38. 0xd34df00dwerehuman /23 29.07.2011 19:49 Azoth_primary

ШТО

39. 0xd34df00dwerehuman /30 29.07.2011 19:49 Azoth_primary

Задача, бля.

40. werehuman0xd34df00d /38 29.07.2011 19:49 Psi+

ну сами вызовы выглядят по-разному

41. werehuman0xd34df00d /39 29.07.2011 19:49 Psi+

разве нет?

42. 0xd34df00dwerehuman /21 29.07.2011 19:49 Azoth_primary

Я на нем привык реальные задачи решать, а не хуйню какую-то.

43. 0xd34df00dwerehuman /40 29.07.2011 19:50 Azoth_primary

И што? Функции-то с одним и тем же именем.

44. werehuman0xd34df00d /43 29.07.2011 19:50 Psi+

ну ок, ок

45. werehuman0xd34df00d /42 29.07.2011 19:51 Psi+

отмазка же. Как видишь, задача вполне реальная. Она реальна хотя бы потому, что она потребовалось не из-за моей дурной похоти.

46. 0xd34df00dwerehuman /45 29.07.2011 19:55 Azoth_primary

А из-за дурной похоти работодателя. Ок, это сразу делает ее реальной.
А если у них в продакшене возникла такая задача, то за такое надо отрывать руки и ебашить ими по еблищу.

47. werehuman0xd34df00d /46 29.07.2011 19:56 Psi+

ты упал в моих глазах как программист. «не работает — не нужно» это хуёвый ответ

48. 0xd34df00dwerehuman /47 29.07.2011 19:57 Azoth_primary

Не «не работает — не нужно», а «подобные потребности и задачи в продакшене говорят о том, что архитектура и дизайн — говно».

49. DZhonwerehuman /47 29.07.2011 19:57 DZhon-ПК

Мы все все понели, пасибо.

50. DZhon0xd34df00d /46 29.07.2011 19:58 DZhon-ПК

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

51. 0xd34df00dDZhon /50 29.07.2011 19:58 Azoth_primary

Там прослеживается паттерн в подобных вещах — const T& f() const; и T f();. И только такое применение, ИМХО, нормально, собсна, я и сам так N раз делал.

52. DZhon0xd34df00d /51 29.07.2011 19:59 DZhon-ПК

Да, ну это частный случай данной "задачи" (TM).

53. werehuman0xd34df00d /51 29.07.2011 19:59 Psi+

да ты уже убедил меня, что нормальный вариант

54. DZhonwerehuman /53 29.07.2011 20:01 DZhon-ПК

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

55. werehumanDZhon /54 29.07.2011 20:02 Psi+

будто проблема сделать не-const из const, особенно если мы уверены, что это не повлечёт дурных последствий

56. 0xd34df00dDZhon /54 29.07.2011 20:03 Azoth_primary

При консте не будет модифицирована та копия, которая справа.

57. 0xd34df00dwerehuman /55 29.07.2011 20:03 Azoth_primary

Повлечет, сука, повлечет. const_cast → UB _всегда_.

58. werehuman0xd34df00d /57 29.07.2011 20:03 Psi+

что есть ub?

59. DZhon0xd34df00d /56 29.07.2011 20:04 DZhon-ПК

Да, но мы про этот паттерн, если я не потерял нить. Я про именно _его_ смысл.

60. werehumanDZhon /59 29.07.2011 20:04 Psi+

паттерн подошёл же под описанный смысл

61. DZhonwerehuman /55 29.07.2011 20:05 DZhon-ПК

ну бывает, что пишут конст версию, а потом в неконст версии делают вызов конст + const_cast, чтобы не дублировать код. Опять же, отсылка к Майерсу.

62. 0xd34df00dwerehuman /58 29.07.2011 20:06 Azoth_primary

Undefined behavior, ебаный стыд.

63. werehuman0xd34df00d /62 29.07.2011 20:06 Psi+

да тут сама задача предполагает твой UB.

64. DZhonwerehuman /60 29.07.2011 20:06 DZhon-ПК

Ну как сказать, результат формально разный (из-за наличия ссылки), но значение (как диктует то логика и смысл), одинаковое.

65. 0xd34df00dwerehuman /63 29.07.2011 20:07 Azoth_primary

Олсо, гыгы, можно функции в разных скоупах/неймспейсах объявить.

66. DZhon0xd34df00d /65 29.07.2011 20:08 DZhon-ПК

Думал об этом, но тут уже точно не перегрузка, а неведомая хуйня. Еще можно запхнуть внутрь макросов, еще можно сказать, что это шаблоны функций и написать разные специализации, etc.

67. jtootf 29.07.2011 21:28

http://codepad.org/6RVU81nM

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

68. ulidtko 29.07.2011 21:54

вот и я удивляюсь, что out-параметры за целый тред не упомянули.

69. 0xd34df00dulidtko /68 29.07.2011 21:55 Azoth_primary

Нестандартное мышление!

70. ulidtkojtootf /67 29.07.2011 21:56

/67, мобильная вебморда глючит =/

71. jtootfulidtko /68 29.07.2011 21:59

ну да. если бы задача не ставилась именно так, как она ставится (с одинаковыми аргументами), можно было бы out-параметром и обойтись

72. werehumanjtootf /67 30.07.2011 06:53

я пытался так сделать, у меня не компилилось =/ Потому что забыл объявление самого шаблона функции. Учить и учить мне плюсы.

73. jtootfwerehuman /72 30.07.2011 08:44 galois

C++ is helluva drugs

74. rapture 30.07.2011 08:45 unknown

Мне кажется, или в базовых хаскельных функциях такое часто встречается?

75. werehumanrapture /74 30.07.2011 08:51 Psi+

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

76. rapturewerehuman /75 30.07.2011 08:53 unknown

А не похуй, если в результате получается одно и то же? "А если нет разницы". Так шаблоны лучше? :)

77. DZhonrapture /76 30.07.2011 08:54 Psi+

Ну вот кстати, если выбирать между специализацией и перегрузкой, то с перегрузкой будет все проще. Чтобы не наступать на грабли.

78. raptureDZhon /77 30.07.2011 08:55 unknown

Грабли? Мы заинтригованы, продолжай.

79. werehumanrapture /76 30.07.2011 08:55 Psi+

извини, можно заниматься секасом в цветок, можно играть на кожаной флейте на заднем дворе. В результате получается одно и то же.

80. rapturewerehuman /79 30.07.2011 08:56 unknown

У меня не так много опыта, чтобы для меня была видна разница.

82. werehumanrapture /80 30.07.2011 08:57 Psi+

а голова недостаточно развитая, чтобы провести эксперимент на модели?

83. rapturewerehuman /82 30.07.2011 09:04 unknown

Умишком не вышел. А ты, умный, дрочи дальше.

84. 0xd34df00drapture /76 30.07.2011 10:29 Azoth_primary

Пиздец.

85. rapture0xd34df00d /84 30.07.2011 10:29 unknown

Это не пиздец, это вопрос.

86. jtootfrapture /74 30.07.2011 11:13

такое же — нет. ad-hoc перегрузка в Haskell работает только благодаря классам типов, и вне контекста точно так же потребует явного указания типов:

Prelude Control.Monad> return 1 :: [Int]
[1]
Prelude Control.Monad> return 1 :: Maybe Int
Just 1

Do you really want to delete ?