C++ 阅读时间 4 分钟

高水平 C++ 开发者在现代标准兴起之前是如何编写现代代码的

分享本文
How Advanced C++ Developers Wrote Modern Code Before the Rise of Modern Standards

在 C++11 及后续标准出现之前,高水平的 C++ 开发者必须找到富有创意的方式来编写现代、可维护且高效的代码。以下是一些他们实现后来才被标准化的特性的例子:

1- shared_ptr

智能指针在 C++ 中已经被使用了很长时间,通常通过自定义实现或 Boost 等库来实现。对许多 C++ 开发者来说,标准库引入shared_ptr及其他智能指针,只是将他们已经在使用的工具标准化而已。

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

2- 基于范围的循环

BOOST_FOREACH是 C++ 中 Boost 库提供的一个宏,用于简化对容器的遍历。它早于 C++11 引入的基于范围的 for 循环,提供了一种编写更简洁、更可读代码的方式。

#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)

在概念出现之前,enable_if(来自<type_traits>)被用于根据类型特征有条件地启用函数模板和类特化。它更加冗长、更难阅读,往往导致复杂的语法。

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

4- Lambda 表达式

Boost Lambda 库使得在 C++ 中创建小型匿名函数对象(lambda)成为可能,可以在需要函数对象或仿函数的地方内联使用。这对于短小的操作特别有用,使代码更简洁、更可读。

#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;
}

这段代码打印出 vector 中每个元素乘以 2 的结果。

5- constexpr

在constexpr于 C++11 中引入之前,开发者常常依赖 Boost 来实现类似的编译期常量求值。Boost 库提供了多种实用工具和技术,可以帮助模拟constexpr。

虽然不是直接的替代品,BOOST_STATIC_ASSERT可用于强制执行编译期断言,确保某些条件在编译期间得到满足。

示例:

#include <boost/static_assert.hpp>

BOOST_STATIC_ASSERT(sizeof(int) == 4);

Boost.MPL 还提供了编译期计算工具,可用于在模板元编程中实现类似constexpr的行为。

示例:

#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));

最后,Boost.Hana 是一个现代元编程库,提供更强大、更灵活的编译期能力,类似于constexpr。

示例:

#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)

::std::is_same,std::enable_if等。
Boost:boost::is_same,boost::enable_if等。

  • Boost 为模板元编程提供了类型特征和 SFINAE 工具。

示例:

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

7- 静态断言

::static_assert
Boost:BOOST_STATIC_ASSERT

  • Boost 支持编译期断言,以便及早捕获错误。

示例:

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

8- 正则表达式

::std::regex
Boost:boost::regex

  • Boost 提供了功能强大的正则表达式库。

示例:

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

9- 元组(Tuples)

::std::tuple
Boost:boost::tuple

  • Boost 提供了从函数返回多个值的方式。

示例:

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

10- Chrono

::std::chrono
Boost:boost::chrono

  • Boost 提供了时间间隔和时钟的实用工具。

示例:

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

11- 线程

::std::thread
Boost:boost::thread

  • Boost 在线程被标准化之前就提供了线程能力。

示例:

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

以下是更多例子,展示 Boost 如何在特性被 C++11 及后续版本标准化之前就提供了相应功能:

12- 函数对象

::std::function
Boost:boost::function

  • Boost 提供了boost::function用于存储可调用对象。

示例:

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

13- Bind

::std::bind
Boost:boost::bind

  • Boost 使得绑定函数参数和创建部分函数应用成为可能。

示例:

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

14- Optional

::std::optional
Boost:boost::optional

  • Boost 提供了boost::optional用于可选值,对于可能不返回值的函数很有用。

示例:

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

15- Any

::std::any
Boost:boost::any

  • Boost 提供了一种类型安全的容器,可保存任意类型的单个值。

示例:

#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

::std::variant
Boost:boost::variant

  • Boost 提供了一种类型安全的联合体,可保存多种类型之一。

示例:

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

17- Filesystem

::std::filesystem
Boost:boost::filesystem

  • Boost 提供了文件系统操作的功能。

示例:

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

结论

Boost 在历史上填补了 C++ 标准库的许多空白,提供了后来被 C++ 标准采纳的高级特性和实用工具。这些例子展示了 Boost 如何帮助 C++ 开发者在这些特性于 C++11 及后续版本中被正式标准化之前,就能编写更具表达力、更高效的代码。

分享本文