【发布时间】:2022-01-05 06:07:53
【问题描述】:
在重构我的项目以与模块一起使用之前,我编写了一个测试项目ExImMod,看看我是否可以分离出模块文档中宣传的声明和定义。对于我的项目,我需要将声明和定义保存在单独的翻译单元 (TU) 中,根据 Modules 文档,这也是可能的。我不想使用模块分区。
不幸的是,我的测试ExImMod 项目表明它们不能完全分离,至少对于 Visual Studio 2022 (std:c++latest) 编译器 (VS22) 而言是这样。
这是我的主要测试程序:
// ExImModMain.cpp
import FuncEnumNum;
import AStruct;
int main()
{
A a;
a.MemberFunc();
}
A 的成员函数 MemberFunc() 在这里声明:
// AStruct.ixx
// module; // global fragment moved to AMemberFunc.cppm (Nicol Bolas)
// #include <iostream>
export module AStruct; // primary interface module
export import FuncEnumNum; // export/imports functionalities declared in FuncEnumNum.ixx and defined in MyFunc.cppm
#include "AMemberFunc.hxx" // include header declaration
其中包括 `AMemberFunc.hxx' 声明和定义:
// AMemberFunc.hxx
export struct A
{
int MemberFunc()
{
if( num == 35 ) // OK: 'num' is defined in primary interface module 'FuncEnumNum.ixx'
{
std::cout << "num is 35\n"; // OK: 'cout' is included in global fragment
}
num = MyFunc(); // OK: 'MyFunc' is declared in primary interface module and defined in 'MyFunc.cppm' module unit
if( hwColors == HwColors::YELLOW ) // OK: 'hwColors' is declared in primary interface module
{
std::cout << "hwColor is YELLOW\n";
}
return 44;
}
};
这是使用函数、枚举和 int 功能的定义:
// AMemberFunc.hxx
export struct A
{
int MemberFunc()
{
if( num == 35 ) // OK: 'num' is defined in primary interface module 'FuncEnumNum.ixx'
{
std::cout << "num is 35\n"; // OK: 'cout' is included in global fragment
}
num = MyFunc(); // OK: 'MyFunc' is declared in primary interface module and defined in 'MyFunc.cppm' module unit
if( hwColors == HwColors::YELLOW ) // OK: 'hwColors' is declared in primary interface module
{
std::cout << "hwColor is YELLOW\n";
}
return 44;
}
};
本 TU 声明了以下功能:
// FuncEnumNum.ixx
export module FuncEnumNum; // module unit
export int num { 35 }; // OK: export and direct init of 'num'
export int MyFunc(); // OK: declaration of 'MyFunc'
export enum class HwColors // OK: declaration of enum
{
YELLOW,
BROWN,
BLUE
};
export HwColors hwColors { HwColors::YELLOW }; // OK: direct init of enum
MyFunc() 在单独的 TU 中定义:
// MyFunc.cppm
module FuncEnumNum; // module implementation unit
int MyFunc() // OK: definition of function in module unit
{
return 33;
}
这意味着MemberFunc() 定义在主界面中,可以正常工作。但这并不能满足我的项目所需。为了测试这一点,我删除了MemberFunc() 的定义;
// AMemberFunc.hxx
export struct A
{
int MemberFunc(); // declares 'MemberFunc'
};
并将其放在单独的 TU 中:
// AMemberFunc.cppm
module;
#include <iostream>
module MemberFunc; // module unit
import AStruct; // (see Nicol Bolas answer)
int MemberFunc()
{
if( num == 35 ) // OK
{
std::cout << "num is 35\n"; // OK
}
num = MyFunc(); // OK
if( hwColors == HwColors::YELLOW ) OK
{
std::cout << "hwColor is YELLOW\n";
}
return 44;
}
但是当实现在单独的模块中时,VS22 找不到 'num'、'MyFunc' 和 'HwColor' 的声明。
我对模块的理解是,如果我导入一个接口,就像我在import FuncEnumNum; 中所做的那样,那么它的所有声明和定义都应该在后续模块中可见。好像不是这样的。
关于为什么这在这里不起作用的任何想法?
【问题讨论】:
-
答案不应整合到问题中。您可以将它们作为答案发布;可以回答你自己的问题。
标签: c++ c++20 visual-studio-2022 c++-modules