1. C++ / Говнокод #22338

    −12

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    #include <iostream>
    using namespace std;
    struct GetFirst{};
    template<class T>
    const T &operator,(const T &val, const GetFirst &) {
      return val;
    }
    template<class T, class U>
    const T &ifvoid_impl(const T &val, const U &) {
      return val;
    }
    template<class T>
    const T &ifvoid_impl(const GetFirst &, const T &val) {
      return val;
    }
    #define ifvoid(X, Y) (ifvoid_impl(((X), GetFirst()), (Y)))
    
    int a() { return 1; }
    void f() {}
    
    int main() {
      cout << ifvoid(a(), "[a()]") << endl
           << ifvoid(f(), "[f()]") << endl;
    }

    Лень проверять в шаблонном коде, возвращает ли что-то пользовательская функция? Воспользуйся волшебством оператора запятая!

    Запостил: Bobik, 16 Февраля 2017

    Комментарии (20) RSS

    • hello, darkness UB, my old friend... I've come toSegmentation fault
      Ответить
      • Где тут UB, Antervis?
        Ответить
        • Где тут Antervis, Bobik?
          Ответить
        • захват prvalue по ссылке.
          Ответить
          • Ткни в строчку в коде и в строчку в стандарте (или cppreference). Пока не вижу уб.
            Ответить
            • Хуест, а это всегда так было?
              Помню я студентом делал лабы в visual studio, где передавал rvalue по ссылке. А на gcc оно даже не компилилось..
              Ответить
              • Код из оппоста всегда работал. Наверное ты что-то не то делал. Может по неконстантной ссылке пытался передать.
                Ответить
          • А разве временный объект с результатом a() не должен дожить до конца стейтмента?

            A temporary bound to a reference parameter in a function call (5.2.2) persists until the completion of the full expression containing the call.

            Вроде как строки 22-23 составляют один full expression...
            Ответить
            • Вот будет ржака, если выяснится, что антервис все это время старательно сохранял временные объекты в переменные.
              Ответить
            • да знаю я, что должен. И знаю, что конкретно в этом коде UB действительно нет.
              А вот напишешь decltype(auto) val = ifvoid(a(), "text"); cout << val; и словишь
              Ответить
              • > И знаю, что конкретно в этом коде UB действительно нет.

                Вот это отмазался. Скорее беги убирать лишние переменные из кода, пока никто не увидел.
                Ответить
              • Забавно, что:
                const T& f(const T& val) { return val; };
                
                {
                    const T& x = T(); // T доживёт до скобки
                    const T& x = f(T()); // T подохнет в конце этой строки
                }
                Ответить
                • Столь же забавно, что:
                  for (auto i : T()) { // T доживёт до скобки
                  }
                  
                  for (auto i : f(T())) { // T подохнет в середине этой строки
                  }
                  Ответить
    • Чет аж интересно стало самому сделать. Минимальный вариант через перегрузку:
      http://ideone.com/9hNmMo
      (без std::enable_if и callable-объектов)
      Ответить
      • А вот и полноценная метаебля с std::enable_if, callable и perfect forwarding'ом:
        http://ideone.com/I8FV5N

        п.с. ideone, втф, меняешь nullptr на 0 и не компилится
        Ответить
        • Ути мой метапрограммист, иди сюда я тебя чмокну.
          Ответить
      • C++11 не считается!!!
        Ответить

    Добавить комментарий