// 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
总结如下:
为什么符号导出失败?
更令人费解的是,为什么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
),但是这样显然会产生歧义当两者都可用时,尝试使用一个