werehuman
29.07.2011 19:10 Psi+
Знакомому при собеседовании в достаточно престижную кампанию задали вопрос: можно ли перегрузить функцию так, чтобы имя и аргументы были одинаковые, а результаты разные. Знакомый резво сказал "нет". Оказалось, это неправильно, но как это сделать не сказали.
Я тут за полчаса додумался как реализовать такую штуку. Может, кто предложит идею лучше моей?
Recommended by:
@Kona-chan
const
"один мой знакомый" говоришь
нет, не я
опа, не додумался. Я нагородил костыли
Покажи.
сначала ты
void f (int, char*);
int f (int, char*) const;
Ок.
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
нахуй так жить, если бы они сказали, что метод, то было бы очевидно. А то вроде и ответ знаешь, а сформулировано так, чтобы не в ту степь вообще думалось.
конст-квалификации доступна только для методов, ебаный стыд
мой костыль. Это уже не функции, конечно, но оно работает. http://pastebin.com/NK64D58a
К тому же точной формулировки я не знаю.
люблю c++
Однохуйственно, это надо просто знать :)
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
кастани к консту, неоднозначный вызов же
ну-ка покажи как
static_cast<const Govno>
получилось.
Govno().test();
a = static_cast<const Govno>(Govno()).test();
Нахуй так жить?
Не хочешь грязи — не лезь в плюсы, хуле.
есть ещё решения? Ну же, пасаны, вы же профессионалы С++, у вас гонору столько, что вы заставляете меня смущаться, глядя на вас!
По-моему все логично, хоть и вербозно.
теряется смысл перегрузки. Ты просто сделал функцию /* метод */ с новым именем, который помимо исходных символов содержит <>, const и
нутыпонел
ваще-то ты мог с самого начала создать конст объект и не объебываться с кастом
const Govno a; Govno b; std::cout << a.test() << " " << b.test() << std::endl;
Опять же, две разные "функции" с разными названиями: a.test() и b.test()
и неочевидно шопесдец. Проще было сделать Govno<void> a и Govno<int> b
то, что ты абсолютно разные функции делаешь перегруженными с одним именем — это твои проблемы, вот честно
/0
нечем отмазаться — не кричи, что умный
пруфани-ка. А так, во всех книжках по плюсах об этом аспекте пишут, например, Скотт Майерс, 55 советов.
учись читать. «Знакомому при собеседовании в достаточно престижную кампанию задали вопрос: можно ли перегрузить функцию так, чтобы имя и аргументы были одинаковые, а результаты разные. Знакомый резво сказал "нет". Оказалось, это неправильно, но как это сделать не сказали.»
стоп, я просил пруф на "нечем отмазаться — не кричи, что умный". U, в общем.
ты мне стал лечить, что моя задача тупая. Я не спрашивал, тупая ли моя задача. Я спрашивал как её решить. А ты, когда зафейлил, стал гнать на мой идиотизм.
Это для member-функций же.
напиши готовый snippet, который вставил и работает
Это же очевидно.
ШТО
Задача, бля.
ну сами вызовы выглядят по-разному
разве нет?
Я на нем привык реальные задачи решать, а не хуйню какую-то.
И што? Функции-то с одним и тем же именем.
ну ок, ок
отмазка же. Как видишь, задача вполне реальная. Она реальна хотя бы потому, что она потребовалось не из-за моей дурной похоти.
А из-за дурной похоти работодателя. Ок, это сразу делает ее реальной.
А если у них в продакшене возникла такая задача, то за такое надо отрывать руки и ебашить ими по еблищу.
ты упал в моих глазах как программист. «не работает — не нужно» это хуёвый ответ
Не «не работает — не нужно», а «подобные потребности и задачи в продакшене говорят о том, что архитектура и дизайн — говно».
Мы все все понели, пасибо.
Справедливости ради, оператор индексирования примерно так обычно и перегружают.
Там прослеживается паттерн в подобных вещах — const T& f() const; и T f();. И только такое применение, ИМХО, нормально, собсна, я и сам так N раз делал.
Да, ну это частный случай данной "задачи" (TM).
да ты уже убедил меня, что нормальный вариант
Угу, только давай без придирок. В таком случае значение возвращается то одно, просто при консте оно не может быть модифицировано, т.к. вернется копия. Вот и все. Т.е. семантика не нарушается. Две функции с одним именем имеют одно и то же назначение и смысл, только меняется доступ к результату.
будто проблема сделать не-const из const, особенно если мы уверены, что это не повлечёт дурных последствий
При консте не будет модифицирована та копия, которая справа.
Повлечет, сука, повлечет. const_cast → UB _всегда_.
что есть ub?
Да, но мы про этот паттерн, если я не потерял нить. Я про именно _его_ смысл.
паттерн подошёл же под описанный смысл
ну бывает, что пишут конст версию, а потом в неконст версии делают вызов конст + const_cast, чтобы не дублировать код. Опять же, отсылка к Майерсу.
Undefined behavior, ебаный стыд.
да тут сама задача предполагает твой UB.
Ну как сказать, результат формально разный (из-за наличия ссылки), но значение (как диктует то логика и смысл), одинаковое.
Олсо, гыгы, можно функции в разных скоупах/неймспейсах объявить.
Думал об этом, но тут уже точно не перегрузка, а неведомая хуйня. Еще можно запхнуть внутрь макросов, еще можно сказать, что это шаблоны функций и написать разные специализации, etc.
http://codepad.org/6RVU81nM
из-за специфики работы механизма вывода типов для избежания явного указания шаблонного параметра приходится использовать dummy-функцию с out-параметром. зато почти похоже на перегрузку, и таки для функций
вот и я удивляюсь, что out-параметры за целый тред не упомянули.
Нестандартное мышление!
/67, мобильная вебморда глючит =/
ну да. если бы задача не ставилась именно так, как она ставится (с одинаковыми аргументами), можно было бы out-параметром и обойтись
я пытался так сделать, у меня не компилилось =/ Потому что забыл объявление самого шаблона функции. Учить и учить мне плюсы.
C++ is helluva drugs
Мне кажется, или в базовых хаскельных функциях такое часто встречается?
в хаскелле такой перегрузки функций, как в плюсоподобных, нету. Там просто хитрая система типов, которую с большими оговорками можно сравнить с шаблонами в плюсах.
А не похуй, если в результате получается одно и то же? "А если нет разницы". Так шаблоны лучше? :)
Ну вот кстати, если выбирать между специализацией и перегрузкой, то с перегрузкой будет все проще. Чтобы не наступать на грабли.
Грабли? Мы заинтригованы, продолжай.
извини, можно заниматься секасом в цветок, можно играть на кожаной флейте на заднем дворе. В результате получается одно и то же.
У меня не так много опыта, чтобы для меня была видна разница.
http://www.gotw.ca/publications/mill17.h...
а голова недостаточно развитая, чтобы провести эксперимент на модели?
Умишком не вышел. А ты, умный, дрочи дальше.
Пиздец.
Это не пиздец, это вопрос.
такое же — нет. ad-hoc перегрузка в Haskell работает только благодаря классам типов, и вне контекста точно так же потребует явного указания типов:
Prelude Control.Monad> return 1 :: [Int]
[1]
Prelude Control.Monad> return 1 :: Maybe Int
Just 1