从std中包装C ++功能有时候是个坏主意吗?

时间:2013-10-28 09:07:16

标签: c++

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

如果我为了方便而做了类似的事情,以避免在我的所有文件中写std::using::std怎么办?你认为这是愚蠢的吗?

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

1 个答案:

答案 0 :(得分:2)

  

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

您的包装函数调用很可能会在适当的优化级别上内联,从而导致ZERO开销。例如,检查this case:包含在operator*中的指针解除引用导致与原始指针解引用相同的汇编代码。在优化过程中,可以蒸发许多级别的C ++抽象。

尽管虚拟函数调用不太可能被内联。所以只要有意义就使用普通函数。

  

但是如果我想将std :: mutex包装到MyMutex类中以在调试时添加日志功能呢?

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

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

在您看来,是否值得?

是的,当然。通常的做法是根据标准库设施构建更有用的抽象。

  

如果我为了方便而做了类似的事情,以避免在我的所有文件中编写std ::或using :: std怎么办?你认为这是愚蠢的吗?

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

在大多数情况下,可以在using namespace std文件的头部使用.cppinlucde之后)。但即使这是不可接受的,您也可以在功能级别使用using指令:

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