我在我的一个模板类中修复GCC警告时遇到问题(使用C ++ 11)。我在课堂上有以下成员函数:
void ThrowInvalidArgumentExceptionIfValueIsLessThanMinimumAllowedValue() const {
if (static_cast<std::intmax_t>(value_) < kMinimumValue) {
throw std::invalid_argument{"The specified number " + std::to_string(static_cast<std::intmax_t>(value_)) + " is less than the minimum number " + std::to_string(static_cast<std::intmax_t>(kMinimumValue)) + "."};
}
}
该类具有以下模板签名(使用CRTP惯用法):
template <class TClass,
typename TValue,
std::intmax_t const kMinimumValue,
std::intmax_t const kMaximumValue>
使用模板签名if
时,对具有<DecimalPercentage, std::uint8_t, 0, 100>
条件的行(有意义)引发以下警告:
warning: comparison is always false due to limited range of data type [-Wtype-limits]
我认为有问题的if
条件可能无法编译if (std::numeric_limits<TValue>::is_unsigned && kMinimumValue == 0)
,但我不知道如何修改代码以避免警告。
使用以下版本的GCC:
gcc (SUSE Linux) 4.7.1 20120723 [gcc-4_7-branch revision 189773]
以下是完整的示例:
#include <cstdint>
#include <stdexcept>
template <class TClass,
typename TValue,
std::intmax_t const kMinimumValue,
std::intmax_t const kMaximumValue>
struct A {
A(TValue const kValue) : value_{kValue} {
// NOOP
}
void some_func() const {
if (static_cast<std::intmax_t>(value_) < kMinimumValue) {
throw std::runtime_error{"foo"};
}
}
TValue value_;
};
struct B : public A<B, std::uint8_t, 0, 100> {
B(std::uint8_t const kValue) : A{kValue} {
// NOOP
}
};
int main() {
B temp{0};
temp.some_func();
}
编译示例的命令:g++ main.cc -std=c++11 -Wall -Wextra -pedantic -Wtype-limits
编辑:: 我遇到过std :: enable_if,但我不知道如何使用它。我想有条件地编译该方法,所以我想我需要像std::enable_if<std::is_signed<TValue>::value>::type
这样的东西。有人能引导我走向正确的方向吗?
答案 0 :(得分:1)
unsigned int(uint8_t)永远不会是负数,因此您的检查将始终失败。
static_cast<std::intmax_t>(value_) < kMinimumValue
您正在转换为intmax_t,但编译器知道您在main中传递了一个常量,并且您永远不会实际使用负整数值。