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

    +137

    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
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    #include <iostream>
    
    template <typename T>
    struct Symbol {};
    
    template <>
    struct Symbol<int> {
        static constexpr const char value = 'd';
    };
    template <>
    struct Symbol<float> {
        static constexpr const char value = 'f';
    };
    
    template<std::size_t N, typename T>
    constexpr bool check_arg_part(const char (&s)[N], size_t i, T d)
    {
        if (i == N)
            return true;
    
        if (i < N - 1) {
            if (s[i] == '%') {
                if (s[i + 1] != Symbol<T>::value)
                    return false;
            }
        }
        return check_arg_part(s, i + 1, d);
    }
    
    template<std::size_t N, typename T>
    constexpr bool check_arg(const char (&s)[N], T d) {
        return check_arg_part(s, 0, d);
    }
    
    int main(int , char*[]) {
        std::boolalpha(std::cout);
    
    
        constexpr bool r = check_arg("foo is int: %d", 1);
        std::cout << "Argument integer is correct: " << r << std::endl;
        constexpr bool r1 = check_arg("foo is float:  %f", 1.0f);
        std::cout << "Argument float is correct: " << r1 << std::endl;
        constexpr bool r2 = check_arg("foo is float: %f", 1);
        std::cout << "Argument int is correct: " << r2 << std::endl;
    
        return 0;
    }

    По мотивам http://govnokod.ru/17925:

    Функция в compile time проверяет соответствие типов. Работает на clang и почему-то валится на gcc.

    Запостил: gorthauer87, 09 Апреля 2015

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

    • показать все, что скрыто> почему-то валится на gcc
      check_arg_part скомпилится только в c++14 т.е. gcc 5.0+. А на прошлых версиях придётся потрахаться с утрамбовкой всей этой логики в один return.

      https://gcc.gnu.org/projects/cxx1y.html
      Ответить
      • показать все, что скрыто> А на прошлых версиях придётся потрахаться с утрамбовкой всей этой логики в один return.
        Эм.. А так не прокатит?
        return i == N || s[i] == '%' && s[i + 1] != Symbol<T>::value || check_arg_part(s, i + 1, d);
        Ответить
        • показать все, что скрытоПрокатит. Но это и есть утрамбовка в один return. А насчёт потрахаться - ты вот код с первого раза неправильно сконвертил. Там же return false, а не return true.

          Как-то так, если я тоже не затупил:
          return i == N || (i >= N - 1 || s[i] != '%' || s[i + 1] == Symbol<T>::value) && check_arg_part(s, i + 1, d);
          
          return i == N || (i < N - 1 && s[i] == '%' && s[i + 1] != Symbol<T>::value ? false : check_arg_part(s, i + 1, d));
          В общем без c++14 жопа с этими constexpr функциями. Хоть и полегче, чем до c++11.
          Ответить
    • показать все, что скрытоУрезанный он какой-то. Да хоть %%. А ещё спецификаторы ширины, выравнивания, точности. А звёздочка чего стоит)))
      Ответить
      • показать все, что скрытоЭто да: по хорошему он должен в последовательности искать спецификатор и возращать tuple с полученной информацией, а ещё сверху должна быть variadic temlate функция, которая по списку параметров будет получать список tuple с результатом разбора. Но не слишком ли сложно для говнокода?
        Ответить
    • показать все, что скрытоgorthauer87 - ты чувак с Хабра, который по qt?
      Ответить
    • Автор изобретает __attribute(( format() ))__?
      Ответить

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