C++20模块无法导出类专门化

lhcgjxsq  于 2024-01-09  发布在  其他
关注(0)|答案(1)|浏览(192)

我无法在Microsoft Visual Studio Community中编译以下C++代码:

  1. // extensions.ixx
  2. export module helpers.extensions;
  3. import <string_view>;
  4. import <type_traits>;
  5. import <format>;
  6. export template <typename T>
  7. concept CEnum = requires(T t)
  8. {
  9. requires std::is_enum_v<T>;
  10. };
  11. export template <CEnum Enum>
  12. struct std::formatter<Enum> : std::formatter<std::string>
  13. {
  14. constexpr auto format(Enum e, std::format_context& ctx) const
  15. {
  16. return formatter<string>::format(std::format("{}", "123"), ctx);
  17. }
  18. };
  19. export template <typename ostream, CEnum Enum>
  20. constexpr ostream& operator<<(ostream& out, const Enum& en)
  21. {
  22. return out << std::format("{}", en);
  23. }
  24. // main.cpp
  25. import helpers.extensions;
  26. #include <iostream>
  27. #include <format>
  28. using namespace std;
  29. enum class Terminal
  30. {
  31. TK_EOF
  32. };
  33. int main()
  34. {
  35. cout << Terminal::TK_EOF << endl;
  36. }

字符串
这是我收到的错误:

  1. 1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\format(3697,19): error C2338: static_assert failed: 'Cannot format an argument. To make type T formattable, provide a formatter<T> specialization. See N4950 [format.arg.store]/2 and [formatter.requirements].'
  2. 1>(compiling source file 'main.cpp')
  3. 1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\format(3697,19):
  4. 1>the template instantiation context (the oldest one first) is
  5. 1> C:\Users\Aakash\source\repos\EfficientCompiler\EfficientCompiler\main.cpp(15,10):
  6. 1> see reference to function template instantiation 'ostream &operator <<<std::ostream,Terminal>(ostream &,const Enum &)' being compiled
  7. 1> with
  8. 1> [
  9. 1> ostream=std::ostream,
  10. 1> Enum=Terminal
  11. 1> ]
  12. 1> C:\Users\Aakash\source\repos\EfficientCompiler\Reflection\extensions.ixx(24,24):
  13. 1> see reference to function template instantiation 'std::string std::__p2286::format<const Enum&>(const std::basic_format_string<char,const Enum &>,const Enum &)' being compiled
  14. 1> with
  15. 1> [
  16. 1> Enum=Terminal
  17. 1> ]
  18. 1> C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\format(3830,42):
  19. 1> see reference to function template instantiation 'auto std::make_format_args<std::format_context,const Enum&>(const Enum &)' being compiled
  20. 1> with
  21. 1> [
  22. 1> Enum=Terminal
  23. 1> ]
  24. 1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\format(679,73): error C2672: 'std::_Format_arg_traits<_Context>::_Type_eraser': no matching overloaded function found
  25. 1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\format(679,73): error C2672: with
  26. 1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\format(679,73): error C2672: [
  27. 1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\format(679,73): error C2672: _Context=std::format_context
  28. 1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\format(679,73): error C2672: ]
  29. 1>(compiling source file 'main.cpp')
  30. 1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\format(676,17):
  31. 1>could be 'auto std::_Format_arg_traits<_Context>::_Type_eraser(void)'
  32. 1> with
  33. 1> [
  34. 1> _Context=std::format_context
  35. 1> ]
  36. 1> C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\format(679,73):
  37. 1> the associated constraints are not satisfied
  38. 1> C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\format(839,11):
  39. 1> the concept 'std::_Formattable_with<const Terminal,std::format_context,std::formatter<Terminal,_CharT>>' evaluated to false
  40. 1> with
  41. 1> [
  42. 1> _CharT=char
  43. 1> ]
  44. 1> C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\format(653,29):
  45. 1> the concept 'std::semiregular<std::formatter<Terminal,_CharT>>' evaluated to false
  46. 1> with
  47. 1> [
  48. 1> _CharT=char
  49. 1> ]
  50. 1> C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\concepts(255,23):
  51. 1> the concept 'std::copyable<std::formatter<Terminal,_CharT>>' evaluated to false
  52. 1> with
  53. 1> [
  54. 1> _CharT=char
  55. 1> ]
  56. 1> C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\concepts(248,20):
  57. 1> the concept 'std::copy_constructible<std::formatter<Terminal,_CharT>>' evaluated to false
  58. 1> with
  59. 1> [
  60. 1> _CharT=char
  61. 1> ]
  62. 1> C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\concepts(170,30):
  63. 1> the concept 'std::move_constructible<std::formatter<Terminal,_CharT>>' evaluated to false
  64. 1> with
  65. 1> [
  66. 1> _CharT=char
  67. 1> ]
  68. 1> C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\concepts(105,30):
  69. 1> the concept 'std::constructible_from<std::formatter<Terminal,_CharT>,std::formatter<Terminal,_CharT>>' evaluated to false
  70. 1> with
  71. 1> [
  72. 1> _CharT=char
  73. 1> ]
  74. 1> C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\concepts(95,8):
  75. 1> the constraint was not satisfied
  76. 1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\format(679,73):
  77. 1>the template instantiation context (the oldest one first) is
  78. 1> C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\format(3700,49):
  79. 1> see reference to class template instantiation 'std::_Format_arg_store<std::format_context,const Enum &>' being compiled
  80. 1> with
  81. 1> [
  82. 1> Enum=Terminal
  83. 1> ]
  84. 1> C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\format(1976,66):
  85. 1> see reference to variable template 'const size_t std::_Format_arg_traits<std::basic_format_context<std::back_insert_iterator<std::_Fmt_buffer<char> >,char> >::_Storage_size<enum Terminal const &>' being compiled
  86. 1> C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\format(682,52):
  87. 1> see reference to alias template instantiation 'std::_Format_arg_traits<_Context>::_Storage_type<_Ty>' being compiled
  88. 1> with
  89. 1> [
  90. 1> _Context=std::format_context,
  91. 1> _Ty=const Terminal &
  92. 1> ]
  93. 1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\format(3490,28): error C2993: 'unknown-type': is not a valid type for non-type template parameter '_Test'
  94. 1>(compiling source file 'main.cpp')
  95. 1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\format(3492,49): error C2641: cannot deduce template arguments for 'std::formatter'
  96. 1>(compiling source file 'main.cpp')
  97. 1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\format(3492,49): error C2783: 'std::formatter<_Ty,_CharT> std::formatter(void)': could not deduce template argument for '_Ty'
  98. 1>(compiling source file 'main.cpp')
  99. 1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\format(3575,5):
  100. 1>see declaration of 'std::formatter'
  101. 1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\format(3492,49): error C2780: 'std::formatter<_Ty,_CharT> std::formatter(std::formatter<_Ty,_CharT>)': expects 1 arguments - 0 provided
  102. 1>(compiling source file 'main.cpp')
  103. 1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\format(3574,1):
  104. 1>see declaration of 'std::formatter'
  105. 1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\format(3493,23): error C2039: 'parse': is not a member of 'std::formatter'
  106. 1>(compiling source file 'main.cpp')
  107. 1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\format(3574,1):
  108. 1>see declaration of 'std::formatter'


如果我将formatter的定义迁移到main.cpp,我就能够成功编译代码:

  1. // extensions.ixx
  2. export module helpers.extensions;
  3. import <string_view>;
  4. import <type_traits>;
  5. import <format>;
  6. export template <typename T>
  7. concept CEnum = requires(T t)
  8. {
  9. requires std::is_enum_v<T>;
  10. };
  11. export template <typename ostream, CEnum Enum>
  12. constexpr ostream& operator<<(ostream& out, const Enum& en)
  13. {
  14. return out << std::format("{}", en);
  15. }
  16. // main.cpp
  17. import helpers.extensions;
  18. #include <iostream>
  19. #include <format>
  20. using namespace std;
  21. enum class Terminal
  22. {
  23. TK_EOF
  24. };
  25. template <CEnum Enum>
  26. struct std::formatter<Enum> : std::formatter<std::string>
  27. {
  28. constexpr auto format(Enum e, std::format_context& ctx) const
  29. {
  30. return formatter<string>::format(std::format("{}", "123"), ctx);
  31. }
  32. };
  33. int main()
  34. {
  35. cout << Terminal::TK_EOF << endl;
  36. }


基于错误,我可以看到编译器无法找到模块中的特殊化,但我正在导出它,并且此特殊化的用法仅存在于模块中(在运算符<<内)。有人能帮助我吗?

相关问题