How advanced C++ developers wrote modern code before the rise of modern standards.

Before the advent of C++11 and subsequent standards, advanced C++ developers had to innovate to write modern, maintainable, and efficient code. Here are some examples of how they proceeded with features that were later standardized:

1- shared_ptr

Smart pointers in C++ have been used for a long time, often through custom implementations or libraries like Boost. For many C++ developers, the introduction of shared_ptr and other smart pointers in the standard library was simply a way to standardize the tools they had already been using.

#include <boost/shared_ptr.hpp>
boost::shared_ptr<int> p(new int(10));

2- Range based loop:

BOOST_FOREACH is a macro provided by the Boost library in C++ to simplify iterating over containers. It predates the range-based for loop introduced in C++11 and offers a way to write cleaner and more readable code.

#include <boost/foreach.hpp>
#include <vector>
#include <iostream>

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};
    BOOST_FOREACH(int& x, vec) {
        std::cout << x << " ";
    }
    return 0;
}

3- C++ Concepts

Before concepts, enable_if from <type_traits> was used to conditionally enable function templates and class specializations based on traits. It is more verbose and harder to read, often leading to complex syntax.

template <typename T>
std::enable_if_t<std::is_integral_v<T>, T> add(T a, T b) {
    return a + b;
}

4- Lambda Expressions:

The Boost Lambda library allows the creation of small unnamed function objects (lambdas) in C++ that can be used inline where a function object or functor is required. This is particularly useful for short operations and makes code more concise and readable.

#include <boost/lambda/lambda.hpp>
#include <iostream>
#include <algorithm>
#include <vector>

int main() {
    using namespace boost::lambda;
    std::vector<int> vec = {1, 2, 3, 4, 5};
    std::for_each(vec.begin(), vec.end(), std::cout << (_1 * 2) << " ");
    return 0;
}

This code prints each element of the vector multiplied by 2.

5- constexpr

Before constexpr was introduced in C++11, developers often relied on Boost to achieve similar compile-time constant evaluation. The Boost library offers several utilities and techniques that can help mimic the behavior of constexpr.

Although not a direct replacement, BOOST_STATIC_ASSERT can be used to enforce compile-time assertions, ensuring that certain conditions are met during compilation.

Example:

#include <boost/static_assert.hpp>

BOOST_STATIC_ASSERT(sizeof(int) == 4);

Boost.MPL provides also tools for compile-time computations, which can be used to achieve behavior similar to constexpr for template metaprogramming.

Example:

#include <boost/mpl/int.hpp>
#include <boost/mpl/plus.hpp>
#include <boost/mpl/equal_to.hpp>
#include <boost/static_assert.hpp>

namespace mpl = boost::mpl;

typedef mpl::int_<3> three;
typedef mpl::int_<4> four;
typedef mpl::plus<three, four>::type seven;

BOOST_STATIC_ASSERT((mpl::equal_to<seven, mpl::int_<7>>::value));

And finally Boost.Hana is a modern metaprogramming library that provides more powerful and flexible compile-time capabilities, similar to constexpr.

Example:

#include <boost/hana.hpp>
#include <iostream>

namespace hana = boost::hana;

constexpr auto sum = hana::int_c<3> + hana::int_c<4>;

int main() {
    std::cout << sum << std::endl; // Outputs: 7
    return 0;
}

6- Type Traits

C++11: std::is_same, std::enable_if, etc.
Boost: boost::is_same, boost::enable_if, etc.

  • Boost provided type traits and SFINAE utilities for template metaprogramming.

Example:

#include <boost/type_traits.hpp>
boost::is_same<int, int>::value; // true

7- Static Assertions

C++11: static_assert
Boost: BOOST_STATIC_ASSERT

  • Boost allowed compile-time assertions to catch errors early.

Example:

#include <boost/static_assert.hpp>
BOOST_STATIC_ASSERT(sizeof(int) == 4);

8- Regular Expressions

C++11: std::regex
Boost: boost::regex

  • Boost provided a powerful regular expression library.

Example:

#include <boost/regex.hpp>
boost::regex re("^[0-9]+$");

9- Tuples

C++11: std::tuple
Boost: boost::tuple

  • Boost provided a way to return multiple values from a function.

Example:

#include <boost/tuple/tuple.hpp>
boost::tuple<int, std::string> t(1, "example");

10- Chrono

C++11: std::chrono
Boost: boost::chrono

  • Boost provided utilities for time duration and clocks.

Example:

#include <boost/chrono.hpp>
boost::chrono::steady_clock::time_point start = boost::chrono::steady_clock::now();

11- Threading

C++11: std::thread
Boost: boost::thread

  • Boost provided threading capabilities before it was standardized.

Example:

#include <boost/thread.hpp>
boost::thread t([]{ std::cout << "Threading with Boost"; });
t.join();

Certainly! Here are some additional examples of how Boost provided functionality before they were standardized in C++11 and later versions:

12- Function Objects

C++11: std::function
Boost: boost::function

  • Boost offered boost::function to store callable objects.

Example:

#include <boost/function.hpp>
boost::function<int(int, int)> f = std::plus<int>();

13- Bind

C++11: std::bind
Boost: boost::bind

  • Boost allowed binding function arguments to create partial function applications.

Example:

#include <boost/bind.hpp>
auto bound_func = boost::bind(std::plus<int>(), 10, _1);
std::cout << bound_func(5); // Outputs 15

14- Optional

C++17: std::optional
Boost: boost::optional

  • Boost provided boost::optional for optional values, useful for functions that might not return a value.

Example:

#include <boost/optional.hpp>
boost::optional<int> maybe_value;
maybe_value = 10;
if (maybe_value) {
    std::cout << *maybe_value;
}

15- Any

C++17: std::any
Boost: boost::any

  • Boost provided a type-safe container for single values of any type.

Example:

#include <boost/any.hpp>
boost::any value = 10;
try {
    std::cout << boost::any_cast<int>(value);
} catch (boost::bad_any_cast &) {
    std::cout << "Bad cast!";
}

16- Variant

C++17: std::variant
Boost: boost::variant

  • Boost provided a type-safe union that can hold one of several types.

Example:

#include <boost/variant.hpp>
boost::variant<int, std::string> var;
var = 10;
std::cout << boost::get<int>(var);

17- Filesystem

C++17: std::filesystem
Boost: boost::filesystem

  • Boost offered functionality for filesystem operations.

Example:

#include <boost/filesystem.hpp>
boost::filesystem::path p("/path/to/file");
if (boost::filesystem::exists(p)) {
    std::cout << "File exists.";
}

Conclusion

Boost has historically filled many gaps in the C++ standard library, providing advanced features and utilities that were later adopted by the C++ standard. These examples show how Boost helped C++ developers write more expressive and efficient code before the features were officially standardized in C++11 and later versions.