Safe Conversion Strategies
Conversion Challenges in C++
Numeric type conversions can lead to unexpected results if not handled carefully. This section explores safe approaches to converting between different numeric types.
Conversion Risk Diagram
graph TD
A[Numeric Conversion] --> B{Check Conversion Safety}
B -->|Safe| C[Perform Conversion]
B -->|Unsafe| D[Handle Potential Overflow]
D --> E[Error Handling]
E --> F[Reject or Adjust Input]
Conversion Methods Comparison
Conversion Method |
Safety Level |
Recommended Use |
static_cast |
Low |
Simple, same-family conversions |
std::stoi/stol |
Medium |
String to integer conversions |
std::numeric_limits |
High |
Precise range checking |
Boost.Numeric.Conversion |
Very High |
Complex numeric conversions |
Safe Conversion Techniques
1. Explicit Range Checking
template <typename DestType, typename SourceType>
bool safeCastWithRangeCheck(SourceType value, DestType& result) {
// Check if source value is within destination type's range
if (value < std::numeric_limits<DestType>::min() ||
value > std::numeric_limits<DestType>::max()) {
return false;
}
result = static_cast<DestType>(value);
return true;
}
int main() {
long long largeValue = 1000000000000LL;
int safeResult;
if (!safeCastWithRangeCheck(largeValue, safeResult)) {
std::cerr << "Conversion would cause overflow" << std::endl;
}
}
2. Safe String to Numeric Conversion
template <typename NumericType>
bool safeStringToNumeric(const std::string& input, NumericType& result) {
try {
// Use std::stoll for long long, std::stod for double, etc.
if constexpr (std::is_same_v<NumericType, int>) {
result = std::stoi(input);
} else if constexpr (std::is_same_v<NumericType, long long>) {
result = std::stoll(input);
} else if constexpr (std::is_same_v<NumericType, double>) {
result = std::stod(input);
}
return true;
}
catch (const std::invalid_argument& e) {
std::cerr << "Invalid input format" << std::endl;
return false;
}
catch (const std::out_of_range& e) {
std::cerr << "Value out of representable range" << std::endl;
return false;
}
}
3. Safe Floating-Point Conversion
bool safeFloatingPointConversion(double value, float& result) {
// Check for infinity or NaN
if (std::isinf(value) || std::isnan(value)) {
return false;
}
// Check range for float
if (value < -std::numeric_limits<float>::max() ||
value > std::numeric_limits<float>::max()) {
return false;
}
result = static_cast<float>(value);
return true;
}
Advanced Conversion Strategies
Boost Numeric Conversion
#include <boost/numeric/conversion/cast.hpp>
template <typename DestType, typename SourceType>
bool boostSafeCast(SourceType value, DestType& result) {
try {
result = boost::numeric_cast<DestType>(value);
return true;
}
catch (boost::numeric::bad_numeric_cast& e) {
std::cerr << "Conversion failed: " << e.what() << std::endl;
return false;
}
}
Best Practices
- Always validate input before conversion
- Use type-specific conversion methods
- Implement comprehensive error handling
- Consider using specialized libraries
At LabEx, we recommend a cautious approach to numeric conversions to prevent unexpected runtime errors.