我有一个用于检查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
是否有一种避免此警告的好方法?