```cpp
#include <iostream>
#include <limits>

int main() {

    // Example 1: Using std::numeric_limits to check for overflow
    int a = 2000000000;
    int b = 1000000000;

    if (b > 0 && a > std::numeric_limits<int>::max() - b) {
        std::cerr << "Integer overflow detected!" << std::endl;
        return 1; 
    } else {
        int c = a + b;
        std::cout << "Result 1: " << c << std::endl;
    }


    // Example 2: Using a larger type for intermediate calculations
    long long a2 = 2000000000;
    long long b2 = 1000000000;
    long long c2 = a2 + b2;

    if (c2 > std::numeric_limits<int>::max() || c2 < std::numeric_limits<int>::min()) {
        std::cerr << "Integer overflow detected!" << std::endl;
        return 1;
    } else {
        int c3 = static_cast<int>(c2);
        std::cout << "Result 2: " << c3 << std::endl;
    }


    // Example 3: Using a safe integer library (Boost.SafeNumerics) - requires installation
    // #include <boost/safe_numerics/safe_integer.hpp>
    // using safe_int = boost::safe_numerics::safe<int>;
    // safe_int a3 = 2000000000;
    // safe_int b3 = 1000000000;
    // safe_int c4 = a3 + b3; // Throws an exception on overflow
    // std::cout << "Result 3: " << c4 << std::endl;



    // Example 4: Saturating arithmetic (clamping the result) - Loss of precision
    int a4 = 2000000000;
    int b4 = 1000000000;
    int c5 = a4 + b4; // Overflow will occur

    if (c5 < a4 && b4 > 0) { // Overflow detection
       c5 = std::numeric_limits<int>::max();
    } else if (c5 > a4 && b4 < 0){ // Underflow detection
        c5 = std::numeric_limits<int>::min();
    }

    std::cout << "Result 4 (saturated): " << c5 << std::endl;



    // Example 5:  Pre-condition checking and input validation
    int a5, b5;
    std::cout << "Enter two integers: ";
    std::cin >> a5 >> b5;

    if(b5 > 0 && a5 > std::numeric_limits<int>::max() - b5){
        std::cerr << "Potential overflow. Please enter smaller numbers." << std::endl;
        return 1;
    }
    if (b5 < 0 && a5 < std::numeric_limits<int>::min() - b5) {
        std::cerr << "Potential underflow. Please enter larger numbers." << std::endl;
        return 1;
    }

    int c6 = a5 + b5;
    std::cout << "Result 5: " << c6 << std::endl;

    return 0;
}
```


These examples demonstrate different strategies to mitigate integer overflow: pre-condition checking, using larger data types, specialized libraries, saturation, and `std::numeric_limits` for compile-time checks and runtime comparisons.  Choose the approach that best suits your application's specific needs and constraints.  The Boost.SafeNumerics example is powerful but requires an external library.  Saturation preserves program execution but at the cost of accuracy.  Input validation and pre-condition checks are crucial, especially when dealing with user-provided input.