Шаблон для проверки ISBN-10 и ISBN-13

#c #templates

#c #шаблоны

Вопрос:

У меня есть функция шаблона для проверки номеров ISBN-10 или ISBN-13:

 #include <algorithm>
#include <vector>
#include <string>
#include <numeric>
#include <functional>
#include <iterator>
#include <iostream>

template <int Size>
bool check_isbn(const std::stringamp; isbn)
{
    std::vector<int> digits{};
    const autoamp; check_char{*(isbn.end() - 1)};
    auto check_digit = check_char == 'X' ? 10 : check_char - '0';
    std::transform(isbn.begin(), isbn.end()-1, std::back_inserter(digits), [](const autoamp; c) {return c - '0'; });
    auto end_digit_it = std::remove_if(digits.begin(), digits.end(), [](const autoamp; digit) {return digit == '-' - '0'; });
    if(end_digit_it - digits.begin() != Size-1) return false;

    int modval{0};
    int sum{0};
    if(Size == 10) {
        modval = 11;
        int factor{10};
        sum = std::accumulate(digits.begin(), end_digit_it, 0, [amp;factor](autoamp; sum, const autoamp; right) { return sum  = factor-- * right; });
    }
    if(Size == 13) {
        modval = 10;
        int factor{3};
        sum = std::accumulate(digits.begin(), end_digit_it, 0, [amp;factor](autoamp; sum, const autoamp; right) {
            factor = 4 - factor; return sum  = factor * right; });
    }

    auto new_check_digit = (modval - sum % modval) % modval;
    return check_digit == new_check_digit;
}


int main()
{
    std::cout << "nISBN10 Check:n";
    std::vector<std::string> isbn_numbers{
        "0321992784", "99921-58-10-7", "9971-5-0210-0", "960-425-059-0",
        "80-902734-1-6", "85-359-0277-5", "1-84356-028-3", "0-684-84328-5",
        "0-8044-2957-X", "0-85131-041-9", "0-943396-04-2", "0-9752298-0-X",
        "0321992384", "99921-52-10-7", "9971-5-3210-0", "960-422-059-0",
        "0-683-84328-5", "0-8024-2957-X", "0-85331-041-9", "0-949396-04-2",
        "0-9722298-0-X", "03216992784", "999621-58-10-7", "9971-56-0210-0",
        "0-80644-2957-X", "0-865131-041-9", "0-9463396-04-2", "0-97526298-0-X"
    };
    for(const autoamp; isbn : isbn_numbers) {
        std::cout << isbn << "tis " << (check_isbn<10>(isbn) ? "ok" : "not ok") << 'n';
    }
    std::vector<std::string> isbn13_numbers{
        "978-0-306-40615-7", "978-0-30h6-40615-7", "978-0-306-40*615-7",
        "978-0-3076-40615-7", "978-0-3086-40615-7", "978-0-303-40615-7"
    };
    std::cout << "nISBN13 Check:n";
    for(const autoamp; isbn13 : isbn13_numbers) {
        std::cout << isbn13 << "tis " << (check_isbn<13>(isbn13) ? "ok" : "not ok") << 'n';
    }

    return 0;
}
  

Во время компиляции я получаю следующее: warning C4127: conditional expression is constant

Полное сообщение:

 1>  main.cpp
1>pathmain.cpp(21): warning C4127: conditional expression is constant
1>  pathmain.cpp(51): note: see reference to function template instantiation 'bool check_isbn<10>(const std::string amp;)' being compiled
1>pathmain.cpp(26): warning C4127: conditional expression is constant
  

Есть ли хороший способ избежать этого предупреждения?

Комментарии:

1. Какая строка генерирует предупреждение?

2. C 1z статический, если? Но, тбх, это выглядит довольно перегруженным. Почему это должно быть шаблоном в первую очередь? Просто включите длину ввода во время выполнения.

3. @BaummitAugen Хорошая мысль. Переключатель времени выполнения работает лучше .

4. Предположительно, компилятор сообщает вам, что вам не нужно проверять, что размер равен 10 или 13, потому что в вашем коде он всегда равен 10 или 13. Следовательно, использование перегруженной функции здесь более оптимально.