【问题标题】:Exporting template function requiring std concepts导出需要标准概念的模板函数
【发布时间】:2022-01-22 06:23:27
【问题描述】:

IDE:MSVS 2022、/std:c++latest/experimental:module、x86;

目标:导出T add(T,T),即requires std::integral<T>

这编译(test.ixx):

export module test;

template < typename T >
concept addable = requires ( T t1, T t2 ) {
    t1 + t2 ;
};

export template < typename T >
requires addable<T>
T add ( T t1, T t2 ) { return t1 + t2; }

这不是(test.ixx):

export module test;

#include <concepts>

export template < typename T >
requires std::integral<T>
T add ( T t1, T t2 ) { return t1 + t2; }

以上代码导致2个错误LNK2019,详情如下;

尝试过

  1. #include &lt;concepts&gt; 在单独的实现文件中 - 失败;
  2. import std.core;,似乎还不支持 - 失败;

使用示例(main.cpp):

import test;
#include <iostream>

int main ()
{
    using namespace std;
   
    int    i = add(22,20);              // = 42
    double d = add(0.5,0.77);           // = 1.27

    cout << i << ", " << d << endl ;    // "42, 1.27"

    return 0;
}

有什么想法吗?

链接器错误详情:

LNK2019 : unresolved external symbol __imp__ldiv::<!test> referenced in function "struct test::_ldiv_t __cdecl div(long,long)" (?div@@YA?AU_ldiv_t@test@@JJ@Z::<!test>)
LNK2019 : unresolved external symbol __imp__lldiv::<!test> referenced in function "struct test::_lldiv_t __cdecl div(__int64,__int64)" (?div@@YA?AU_lldiv_t@test@@_J0@Z::<!test>)

【问题讨论】:

  • "import std.core;,似乎还不支持" 这不是 C++20 的一部分。
  • @NicolBolas 它甚至不会成为 C++23 的一部分 - 会有 std and std.compat

标签: c++ templates c++20 c++-concepts c++-modules


【解决方案1】:

问题是,你不应该在模块声明 export module xxx 之后使用 #include

模块的引入并没有改变#include 的含义(嗯,在大多数情况下),#include 仍然意味着“在此处复制粘贴此文件”。您的#include-ing 或&lt;concepts&gt; 将其所有内容及其传递包含粘贴到您的模块中,您的模块现在“拥有”这些定义(它们具有模块链接)。编译器对属于模块的名称进行了不同的处理,这就是导致链接器错误的原因。

您应该改为使用 全局模块片段 处理 #include-ing 的东西:

module;
#include <concepts>
export module test;
// contents

或者使用“头单元”(如果您的编译器支持它们):

export module test;
import <concepts>;
// contents

【讨论】:

  • 全局模块片段有效,而“标题单元”则无效。目前看来 MSVS 2022 不支持“标题单元”。谢谢你,@Chlorie!
  • 澄清:当使用“标头单元”时,MSVS 编译器会抛出“C7612 找不到...\include\concepts 的标头单元”,因此似乎支持“标头单元”,但是正如@NicolBolas 提到的,导入它们时存在问题。
  • @PiotrTarasov:请注意,编译器可以很好地实现标头单元(或多或少)。他们在将标准库头文件作为头文件单元导入时遇到了麻烦。
猜你喜欢
  • 2016-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-14
  • 1970-01-01
  • 2022-09-29
相关资源
最近更新 更多