导出命名空间
export module name;

export namespace name {
int foo(int fir, int sec);
void bar();
}  // namespace name
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

简单示例

模块文件 simple.ixx

export module simple;  // 模块声明

// 该函数将被导出
export int add(int a, int b) { return a + b; }

 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

export module simple; 是一个模块声明, 它声明了一个模块, 模块名为simple.

在模块中, 我们可以使用export关键字导出函数, 命名空间, 类, 变量等.
这样的实体可被其他模块导入.

主程序 simple_main.cpp

在使用的时候, 使用import simple;导入模块.

import simple; // 导入模块
#include 

int main() {
  std::cout << "simple add(1, 2)=" << add(1, 2) << "\n";
  return 0;
}
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

CMakeList.txt

add_library(simple_module)
target_sources(simple_module
        PUBLIC
        FILE_SET CXX_MODULES FILES
        simple.ixx
)
add_executable(simple_demo simple_main.cpp)
target_link_libraries(simple_demo simple_module)
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

复杂示例

模块文件

请注意如果模块需要引入传统头文件, 需要使用如下写法.

module;

#include 
#include 

export module complex;

export namespace complex {
class Person {
 public:
  Person(unsigned age, std::string name) : age_(age), name_(std::move(name)) {}

  [[nodiscard]] std::string Name() const { return name_; }
  [[nodiscard]] unsigned Age() const { return age_; }

 private:
  unsigned age_;
  std::string name_;
};
}  // namespace complex
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

程序主文件

import complex;
#include 

int main() {
  complex::Person joy(18, "Joy");
  std::cout << "Name: " << joy.Name() << "\n";
  std::cout << "Age : " << joy.Age() << "\n";
  return 0;
}
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

cmake 设置

add_library(complex_module)
target_sources(complex_module
        PUBLIC
        FILE_SET CXX_MODULES FILES
        complex.ixx
)
add_executable(complex_demo complex_main.cpp)
target_link_libraries(complex_demo complex_module)
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

模块接口

当模块变得越来越大时, 可能需要把模块的接口和实现分开. 这样可以更好地组织代码, 并且提高代码的可读性.

模块接口单元

module;

#include 

export module demo;

export namespace demo {

int sum(const std::vector<int>& v);

int prod(const std::vector<int>& v);
}  // namespace demo
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

模块实现单元

module demo;

#include 
#include 

namespace demo {
int sum(const std::vector<int>& v) {
  return std::accumulate(v.begin(), v.end(), 1, std::plus{});
}

int prod(const std::vector<int>& v) {
  return std::accumulate(v.begin(), v.end(), 1, std::multiplies{});
}
}  // namespace demo
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

主程序

import demo;

#include 
#include 

int main() {
  std::vector vec{1, 2, 3, 4, 5};
  std::cout << "sum  : " << demo::sum(vec) << std::endl;
  std::cout << "prod : " << demo::prod(vec) << std::endl;
}
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

cmake 设置如下:

add_library(separate_module)
target_sources(separate_module
        PUBLIC
        FILE_SET CXX_MODULES FILES
        separate_interface.ixx
)
target_sources(separate_module PUBLIC separate_impl.ixx)

add_executable(separate separate_main.cpp)
target_link_libraries(separate separate_module)

 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

子模块

对于大的模块可以将其分割为多个子模块. 然后设置一个主模块文件, 导入并导出子模块.

这里的每一个子模块都是一个独立的模块, 可以单独存在.

模块主文件 sort.ixx

设想一下我们目前有一个排序算法库, 包含几种不同的排序算法, 每种排序算法都可以独立使用.

module;

export module sort;
export import sort.bubble_sort;
export import sort.insert;
export import sort.quick;
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

子模块文件

module;

#include 
#include 

export module sort.bubble_sort;

export namespace sort {
void bubble_sort(std::vector<int>& arr) {
  if (arr.size() < 2) return;
  for (int i = 0; i < arr.size() - 1; i++) {
    auto swapped = false;
    for (int j = 1; j < arr.size() - i; j++) {
      if (arr[j - 1] > arr[j]) {
        std::swap(arr[j - 1], arr[j]);
        swapped = true;
      }
    }
    if (!swapped) break;
  }
}
}  // namespace sort
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
module;

#include 

export module sort.insert;

export namespace sort {

void insertion_sort(std::vector<int>& arr) {
  for (int i = 1; i < arr.size(); i++) {
    auto k = arr[i];
    int j = i - 1;
    while (j >= 0 && arr[j] > k) {
      arr[j + 1] = arr[j];
      j--;
    }
    arr[j + 1] = k;
  }
}

}  // namespace sort
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

程序主文件

import sort;
#include 
#include 
#include 

int main() {
  std::vector v{5, 4, 3, 2, 1};
  sort::bubble_sort(v);
  std::cout << std::boolalpha << std::is_sorted(v.begin(), v.end(), std::less{})
            << std::endl;
}
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

cmake 设置

add_library(sort_module)
target_sources(sort_module
        PUBLIC
        FILE_SET CXX_MODULES FILES
        sort.ixx
        sort_bubble.ixx
        sort_quick.ixx
        sort_insert.ixx
)
add_executable(sort_module_demo sort_main.cpp)
target_link_libraries(sort_module_demo sort_module)
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

模块分区

模块分区与子模块类似, 唯一的区别是分区模块不能作为一个独立模块存在.

模块主文件

module;

export module partition;
export import :part1;
export import :part2;
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

子分区文件

module;

#include 
#include 

export module partition:part1;

export namespace sort {
void bubble_sort(std::vector<int>& arr) {
  if (arr.size() < 2) return;
  for (int i = 0; i < arr.size() - 1; i++) {
    auto swapped = false;
    for (int j = 1; j < arr.size() - i; j++) {
      if (arr[j - 1] > arr[j]) {
        std::swap(arr[j - 1], arr[j]);
        swapped = true;
      }
    }
    if (!swapped) break;
  }
}
}  // namespace sort
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
module;

#include 

export module partition:part2;

export namespace sort {

void insertion_sort(std::vector<int>& arr) {
  for (int i = 1; i < arr.size(); i++) {
    auto k = arr[i];
    int j = i - 1;
    while (j >= 0 && arr[j] > k) {
      arr[j + 1] = arr[j];
      j--;
    }
    arr[j + 1] = k;
  }
}

}  // namespace sort
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

cmake 设置

add_library(partition_module)
target_sources(partition_module
        PUBLIC
        FILE_SET CXX_MODULES FILES
        partition.ixx
        partition_part1.ixx
        partition_part2.ixx
)
add_executable(partition_module_demo partition_main.cpp)
target_link_libraries(partition_module_demo partition_module)
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

总结

参考链接

注:本文转载自blog.csdn.net的程序员阿荣的文章"https://blog.csdn.net/arong_xu/article/details/137088783"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接

评论记录:

未查询到任何数据!