【问题标题】:How can a header file safely include standard libraries for consumers to import them头文件如何安全地包含标准库供消费者导入它们
【发布时间】:2019-06-12 22:52:33
【问题描述】:

假设我想创建以下类:

#pragma once
#include <memory>
#include <string>

namespace stackquestion
{
    struct Logger
    {
        void Log(std::string message);
    private:
        class Impl;
        std::unique_ptr<Impl> impl;
    };
}

当我想发布课程时,我最终取决于我的消费者对std::stringstd::unique_ptr 的定义。我对发布的含义含糊不清。我正在考虑给某人一个用于静态或动态链接的库。

当我退回到没有这些内容的版本时,我最终会失去我想要获得的舒适/安全。

#pragma once

namespace stackquestion
{
    struct Logger
    {
        void Log(const char *);
    private:
        class Impl * impl;
    };
}

我是否缺少灵丹妙药?

【问题讨论】:

  • 标准库的好处在于它是 standard 库。所有符合 C++ 的编译器都会有它。 std 命名空间中的类不是您的消费者,而是它们的 C++ 编译器。
  • 如果消费者有一个自定义的&lt;memory&gt;&lt;string&gt; 会破坏您的代码,那是他们的问题,而不是您的问题。你保证你的代码是符合标准的,你可以免除任何责任。
  • 我的代码符合当时的版本。 std::string 过去发生了变化,使得在翻译单元之间传递时可能发生堆栈损坏。所有参与者都符合某些要求,堆栈已损坏。
  • @Johannes 如果这将是一个 DLL,那么你是对的,你不应该传递标准容器:stackoverflow.com/questions/5347355/…
  • @Johannes All 链接在一起的目标文件、库等应该总是(当然存在例外,但作为一般规则)构建使用 exact same 编译器 - 这意味着相同的标准库。 C++ 从未保证编译器和编译器版本之间的二进制兼容性。

标签: c++ header linker


【解决方案1】:

这两种解决方案都很好,具体取决于您的目标。

包括内存和字符串

这样做不会破坏代码,您会强制他们使用 C++11 或更高版本来使用您的库。不过,我认为这是一个优点,因为您不必为了支持 C++98 而花很多心思。

编译代码时,他们不应该弄乱标准库,所以如果他们做类似#defined unique_ptr shared_ptr 的事情,我会责怪你的用户编码不好,而不是你。是的,你可以尝试防止用户做很多坏事,比如重载operator&amp;(地址),但是,你最终会得到像 STL 实现这样的代码,这也不漂亮。

使用 pimpl

使用 pimple 可以解决上述很多问题。但是,您不应该因此而使用它。 pimple 唯一真正的优势是二进制兼容性。

由于您不公开 STL 或除您自己的以外的任何其他库,因此您不应该在 std::string 上遇到链接错误。 (是的,这是可能的)

如果你用libc++ 编译你的库,std::string 实际上是std::__1::basic_string&lt;char, std::__1::char_traits&lt;char&gt;, std::__1::allocator&lt;char&gt; &gt; 具有特定于libcxx 的内存布局。

如果您使用 libstdc++ 编译库,std::string 将变为 std::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;(或 C++11 变体的更长名称)

详情请见this thread

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-09
    • 1970-01-01
    • 2020-01-29
    • 1970-01-01
    • 1970-01-01
    • 2021-04-28
    • 2018-08-09
    相关资源
    最近更新 更多