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

问题描述 投票:0回答:1

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

// extensions.ixx
export module helpers.extensions;
import <string_view>;
import <type_traits>;
import <format>;

export template <typename T>
concept CEnum = requires(T t)
{
    requires std::is_enum_v<T>;
};

export template <CEnum Enum>
struct std::formatter<Enum> : std::formatter<std::string>
{
    constexpr auto format(Enum e, std::format_context& ctx) const
    {
        return formatter<string>::format(std::format("{}", "123"), ctx);
    }
};

export template <typename ostream, CEnum Enum>
constexpr ostream& operator<<(ostream& out, const Enum& en)
{
    return out << std::format("{}", en);
}


// main.cpp
import helpers.extensions;

#include <iostream>
#include <format>

using namespace std;

enum class Terminal
{
    TK_EOF
};

int main()
{
    cout << Terminal::TK_EOF << endl;
}

这是我收到的错误:

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].'
1>(compiling source file 'main.cpp')
1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\format(3697,19):
1>the template instantiation context (the oldest one first) is
1>  C:\Users\Aakash\source\repos\EfficientCompiler\EfficientCompiler\main.cpp(15,10):
1>  see reference to function template instantiation 'ostream &operator <<<std::ostream,Terminal>(ostream &,const Enum &)' being compiled
1>        with
1>        [
1>            ostream=std::ostream,
1>            Enum=Terminal
1>        ]
1>  C:\Users\Aakash\source\repos\EfficientCompiler\Reflection\extensions.ixx(24,24):
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
1>        with
1>        [
1>            Enum=Terminal
1>        ]
1>  C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\format(3830,42):
1>  see reference to function template instantiation 'auto std::make_format_args<std::format_context,const Enum&>(const Enum &)' being compiled
1>        with
1>        [
1>            Enum=Terminal
1>        ]
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
1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\format(679,73): error C2672:         with
1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\format(679,73): error C2672:         [
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
1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\format(679,73): error C2672:         ]
1>(compiling source file 'main.cpp')
1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\format(676,17):
1>could be 'auto std::_Format_arg_traits<_Context>::_Type_eraser(void)'
1>        with
1>        [
1>            _Context=std::format_context
1>        ]
1>  C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\format(679,73):
1>  the associated constraints are not satisfied
1>      C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\format(839,11):
1>      the concept 'std::_Formattable_with<const Terminal,std::format_context,std::formatter<Terminal,_CharT>>' evaluated to false
1>        with
1>        [
1>            _CharT=char
1>        ]
1>          C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\format(653,29):
1>          the concept 'std::semiregular<std::formatter<Terminal,_CharT>>' evaluated to false
1>        with
1>        [
1>            _CharT=char
1>        ]
1>              C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\concepts(255,23):
1>              the concept 'std::copyable<std::formatter<Terminal,_CharT>>' evaluated to false
1>        with
1>        [
1>            _CharT=char
1>        ]
1>                  C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\concepts(248,20):
1>                  the concept 'std::copy_constructible<std::formatter<Terminal,_CharT>>' evaluated to false
1>        with
1>        [
1>            _CharT=char
1>        ]
1>                      C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\concepts(170,30):
1>                      the concept 'std::move_constructible<std::formatter<Terminal,_CharT>>' evaluated to false
1>        with
1>        [
1>            _CharT=char
1>        ]
1>                          C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\concepts(105,30):
1>                          the concept 'std::constructible_from<std::formatter<Terminal,_CharT>,std::formatter<Terminal,_CharT>>' evaluated to false
1>        with
1>        [
1>            _CharT=char
1>        ]
1>                              C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\concepts(95,8):
1>                              the constraint was not satisfied
1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\format(679,73):
1>the template instantiation context (the oldest one first) is
1>  C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\format(3700,49):
1>  see reference to class template instantiation 'std::_Format_arg_store<std::format_context,const Enum &>' being compiled
1>        with
1>        [
1>            Enum=Terminal
1>        ]
1>  C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\format(1976,66):
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
1>  C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\format(682,52):
1>  see reference to alias template instantiation 'std::_Format_arg_traits<_Context>::_Storage_type<_Ty>' being compiled
1>        with
1>        [
1>            _Context=std::format_context,
1>            _Ty=const Terminal &
1>        ]
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'
1>(compiling source file 'main.cpp')
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'
1>(compiling source file 'main.cpp')
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'
1>(compiling source file 'main.cpp')
1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\format(3575,5):
1>see declaration of 'std::formatter'
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
1>(compiling source file 'main.cpp')
1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\format(3574,1):
1>see declaration of 'std::formatter'
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'
1>(compiling source file 'main.cpp')
1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\format(3574,1):
1>see declaration of 'std::formatter'

如果我将

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

// extensions.ixx
export module helpers.extensions;
import <string_view>;
import <type_traits>;
import <format>;

export template <typename T>
concept CEnum = requires(T t)
{
    requires std::is_enum_v<T>;
};

export template <typename ostream, CEnum Enum>
constexpr ostream& operator<<(ostream& out, const Enum& en)
{
    return out << std::format("{}", en);
}

// main.cpp
import helpers.extensions;

#include <iostream>
#include <format>

using namespace std;

enum class Terminal
{
    TK_EOF
};


template <CEnum Enum>
struct std::formatter<Enum> : std::formatter<std::string>
{
    constexpr auto format(Enum e, std::format_context& ctx) const
    {
        return formatter<string>::format(std::format("{}", "123"), ctx);
    }
};

int main()
{
    cout << Terminal::TK_EOF << endl;
}

根据错误,我可以看到编译器无法找到模块中的专业化,但我正在导出它并且该专业化的用法仅存在于模块中(在运算符

<<
内部)。有人可以帮我吗?

c++ visual-studio module format c++20
1个回答
© www.soinside.com 2019 - 2024. All rights reserved.