用于ISBN-10和ISBN-13检查的模板

时间:2016-10-10 19:21:15

标签: c++ templates

我有一个用于检查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::string& isbn)
{
    std::vector<int> digits{};
    const auto& 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 auto& c) {return c - '0'; });
    auto end_digit_it = std::remove_if(digits.begin(), digits.end(), [](const auto& 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, [&factor](auto& sum, const auto& right) { return sum += factor-- * right; });
    }
    if(Size == 13) {
        modval = 10;
        int factor{3};
        sum = std::accumulate(digits.begin(), end_digit_it, 0, [&factor](auto& sum, const auto& 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 auto& 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 auto& 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>path\main.cpp(21): warning C4127: conditional expression is constant
1>  path\main.cpp(51): note: see reference to function template instantiation 'bool check_isbn<10>(const std::string &)' being compiled
1>path\main.cpp(26): warning C4127: conditional expression is constant

是否有一种避免此警告的好方法?

0 个答案:

没有答案