在 C++20 中混合模块和 headers 是否可能/可接受?

Is mixing modules and headers in C++20 possible / acceptable?

我实际上是在尝试通过编写自己的小模块来理解 C++20 模块系统。假设我想提供一个删除字符串开头和结尾的所有空格的函数(trim 函数)。以下代码可以正常工作

module;

export module String;

import std.core;

export std::string delete_all_spaces(std::string const & string)
{
    std::string copy { string };

    auto first_non_space { std::find_if_not(std::begin(copy), std::end(copy), isspace) };
    copy.erase(std::begin(copy), first_non_space);

    std::reverse(std::begin(copy), std::end(copy));
    first_non_space = std::find_if_not(std::begin(copy), std::end(copy), isspace);
    copy.erase(std::begin(copy), first_non_space);
    std::reverse(std::begin(copy), std::end(copy));

    return copy;
}
import std.core;
import String;

int main()
{
    std::cout << delete_all_spaces("  Hello World!    \n");
    return 0;
}

但是 如果我只想在我的模块中使用特定的 header 而不是 std.core 怎么办? 如果我这样做,替换 import std.core 通过以下代码,我在 Visual Studio 2019 上收到错误。

module;

#include <algorithm>
#include <cctype>
#include <string>

export module String;

// No more import of std.core

export std::string delete_all_spaces(std::string const & string)
{
    // ...
}
Error LNK1179 file not valid or damaged: '??$_Deallocate@[=14=]A@@std@@YAXPAXI@Z' COMDAT duplicated

但是,如果在 main.cpp 中我也将 import std.core 替换为 #include <iostream>,代码将再次编译。这就像 使用两个系统证明链接器来完成它的工作

问题是:我做错了吗?同时使用新的 import 和旧的 #include 方法是一种不好的做法吗?我在 Internet 上的多个帖子中看到,您可以在模块中包含一些旧的 header,从而在不破坏现有代码的情况下使您的代码现代化。但是 如果这个 header 包含 STL 的某些部分,比如 #include <string> 但我的模块使用 import std.core 怎么办?

我只使用 Visual Studio 2019 进行测试,因为截至目前,import std.core 不适用于 GCC。那么,它可能来自 VS 中的错误或者所有编译器的问题都一样吗?

是的,模块可以与 header 文件一起使用。我们可以在同一个文件中导入和包含 headers,这是一个例子:

import <iostream>
#include <vector>
int main()
{
  std::vector<int> v{1,6,8,7};
  for (auto i:v)
    std::cout<<i;
  return 0;
}

创建模块时,您可以自由导出模块接口文件中的实体并将实现移动到其他文件。总而言之,逻辑与管理 .h 和 .cpp 文件的逻辑相同