c++20模块导出/导入


// module A
export module A;
import <type_traits>;
namespace test
{
export{
template<typename T, std::size_t N>
class Foo;
template<typename T>
using Foo1 = Foo<T, 1>;
template<typename T>
struct is_Foo : std::false_type {};
template<typename T, std::size_t N>
struct is_Foo<Foo<T, N>> : std::true_type {};
template<typename T>
constexpr static bool is_Foo_v = is_Foo<T>::value;
template<typename T>
concept Foo_t = is_Foo_v<T>;
}
}
// module B
export module B;
export import module A;
namespace test
{
export{
template<typename T, std::size_t>
class Foo{ ... };
}
}
// module C
export module C;
export import module B;
namespace test
{
export{
// (1)
template<Foo_t T>
constexpr void test_func(const T& t) { ... }
}
}
// test.cpp
import module C;
using namespace test;
constexpr void test_foo()
{
// (2)
constexpr Foo1 f1{1, 2, 3};
// (3)
test_func(f1);
// (4)
constexpr Foo1 f2{4, 5, 6};
}

(1):概念Foo_t在这里工作得很好

(2):使用undefined class test::Foo<int, 1>

虽然编译器输出使用未定义的类,IDE仍然可以提示我们使用Foo1<int> = Foo<int, 1>;

(3):编译器对这一行没有输出,IDE没有报告错误(用红色标记)

(4):与(2)相同

注意:代码都经过了测试,绝对没有语法错误(如果你不编译成一个模块,但使用hpp,代码运行正常)

可能有人注意到模块导入有订单要求,我也测试过,无法解决。

在test.cpp文件中,即使我重新导入所有模块,问题也无法解决。错误仍然是使用undefined class test::Foo<int, 1>

// test.cpp
import module A;
import module B;
import module C;
// not work

总结如下:

  1. 为什么符号导出失败?

  2. 更令人费解的是,为什么IDE可以找到我们使用的符号(虽然jump to definition不能用来跳过),但编译器找不到?

如何解决这个问题?

============================================

经过多次尝试,我似乎已经解决了上述问题(我将多个模块合并为一个模块,将原有内容分成多个子模块),但现在又出现了新的问题。

// module Foo
export module Foo;
export{ 
template<typename T> struct Foo_trait : std::false_type 
{ 
constexpr static auto size = 1; 
}
constexpr auto a_func_base_on_specialization_type_Foo_trait(...) 
{ 
... 
}
}
// module Bar
export module Bar;
import module Foo;
export
{
template<typename T, std::size_t N>
class Baz;
template<typename T, std::size_t N>
struct Foo_trait<Baz<T, N>> : std::true_type { 
constexpr static auto size = N; 
}
}
template<typename T, std::size_t N>
class Baz { 
constexpr Baz(something) : 
data(a_func_base_on_specialization_type_Foo_trait(something)) {} 
}

我发现我不能使用a_func_base_on_specialization_type_Foo_trait来构建类Baz,因为大小仍然是1而不是N

============================================

我似乎已经找到上述问题的原因了

https://developercommunity.visualstudio.com/t/c20-modules-fail-to-pick-up-template-specializatio/1189551

您不能在一个模块(A)中声明test::Foo,并在另一个中定义它模块(B)。标准说这是病态的,不需要诊断;基于其实现者的首选项,MSVC可以将它们解释为两个不同的模板(就好像它们被命名为__A::test::Foo__B::test::Foo),但是这样显然会产生歧义当两者都可用时,尝试使用一个

最新更新