包装 std C++功能有时是一个坏主意

Wrapping C++ functionalities from std, is sometimes a bad idea?

本文关键字:一个 C++ std 功能 包装      更新时间:2023-10-16

我的问题是关于从std库中包装一些容器或对象,以及这样做的成本。假设我需要创建一个ThreadSafeStack类。我会包装std::stack容器并使用互斥锁使其线程安全。这是完全可以的,因为新ThreadSafeStack的功能值得付出代价(函数调用)。但是,如果我想将std::mutex包装到类中,MyMutex在调试时添加日志记录功能怎么办?在您看来,值得与否?

如果我这样做只是为了方便,避免在所有文件中写入std::using::std怎么办?你认为这很愚蠢吗?

我已经阅读了一些关于函数调用的信息(例如),我会说这不会是一个很大的开销。

这是完全可以的,因为新的ThreadSafeStack的功能是值得的(函数调用)。

您的包装函数调用很可能会在适当的优化级别内联,从而导致零开销。例如,检查这种情况:将指针取消引用包装到operator*会导致汇编程序代码与原始指针取消引用相同。在优化过程中,可以蒸发许多级别的C++抽象。

但是,虚拟函数调用不太可能是内联的。因此,只要有意义,就使用正常功能。

但是,如果我想将 std::mutex 包装到一个类 MyMutex 中以在调试时添加日志记录功能怎么办?

日志记录可能会增加一些显著的成本,但如果仅在调试期间需要它 - 您可以通过 ifdef s 或任何其他方式在发布版本上安全地禁用它,例如:

const bool do_logging = false; // somewhere
// ...
if(do_logging) // branching can be easily removed by optimizer,
               // because do_logging is constant
    // ...
else
    // ...

在您看来,值得与否?

是的,当然。通常的做法是基于标准库工具构建更有用的抽象。

如果我这样做只是为了方便,避免在我的所有文件中写入 std:: 或使用::std怎么办?你认为这很愚蠢吗?

这取决于您的项目 - 在某些情况下,甚至可以在头文件中使用 using namespace std。但请注意 - 包含此类标头的人可能会面临名称冲突。

在大多数情况下,可以在.cpp文件的头部使用using namespace stdinlucde s之后)。但即使这是不可接受的,您也可以始终在函数级别使用using指令:

void foo()
{
     using namespace std;
     // ...
}