由于 MSVS2017 中的递归,编译器失败
Compiler fails due to recursion in MSVS2017
我正在使用 boost::hana::string
的编译时功能为 GUI 生成 xaml 标记字符串。
我正在使用配置为 C++17 语言的 VS2017,但有时字符串太长,我收到了来自编译器的下一条消息:
fatal error C1202: recursive type or function dependency context too complex
如果我从字符串中删除几个字符,一切正常,所以我猜是长度相关的。
下一段代码在 gcc 下的 coliru 中运行正常,但在 MSVS2017 中却惨遭失败:
注意:请注意,我已经删除了示例中的所有可配置和模板化变量,以便只关注问题。当然,不值得使用boost::hana之类的示例代码,只是一个最小的工作源。
#include <boost/hana/string.hpp>
constexpr auto markup_ribbon()
{
return (BOOST_HANA_STRING(
"<?xml version='1.0' encoding='iso-8859-1'?>"
"<Border VerticalAlignment='Top'>"
"<Border.Background>"
"<LinearGradientBrush StartPoint='0,0.2' EndPoint='0.8,0.8'>"
"<GradientStop Offset='0' Color='#cd0000'/>"
"<GradientStop Offset='0.75' Color='#fc999e'/>"
"<GradientStop Offset='1' Color='#e4ecf7'/>"
"</LinearGradientBrush>"
"</Border.Background>"
"<StackPanel Orientation='Vertical' TextBlock.FontFamily='Tahoma'>"
"<StackPanel.Resources>"
"<Style TargetType='Path'>"
"<Setter Property='Fill' Value='Blue'/>"
"<Style.Triggers>"
"<Trigger Property='IsMouseOver' Value='True'>"
"<Trigger.Setters>"
"<Setter Property='Fill' Value='Red'/>"
"</Trigger.Setters>"
"</Trigger>"
"</Style.Triggers>"
"</Style>"
"</StackPanel.Resources>"
"<Grid>"
"<Grid.ColumnDefinitions>"
"<ColumnDefinition Width='300'/>"
"<ColumnDefinition Width='*'/>"
"<ColumnDefinition Width='*'/>"
"<ColumnDefinition Width='50'/>"
"<ColumnDefinition Width='200'/>"
"</Grid.ColumnDefinitions>"
"<Image Margin='10' HorizontalAlignment='Left' VerticalAlignment='Center' Source='1'/>"
"<TextBlock Grid.Column='1' HorizontalAlignment='Left' VerticalAlignment='Center' FontSize='44' FontWeight='Bold' Foreground='#ffffff'>ASDF2021</TextBlock>"
"<Image Grid.Column='2' HorizontalAlignment='Left' VerticalAlignment='Top' Source='3'/>"
"<TextBlock Grid.Column='3' HorizontalAlignment='Right' VerticalAlignment='Center'><Hyperlink TextDecorations='' Tag='back' ToolTip='Back to administration screen. Back to administration screen.'><Path Stroke='Purple' StrokeThickness='2' Data='M12.981,9.073V6.817l-12.106,6.99l12.106,6.99v-2.422c3.285-0.002,9.052,0.28,9.052,2.269c0,2.78-6.023,4.263-6.023,4.263v2.132c0,0,13.53,0.463,13.53-9.823C29.54,9.134,17.952,8.831,12.981,9.073z'/></Hyperlink></TextBlock>"
"<TextBlock Grid.Column='4' Margin='0,0,30,0' HorizontalAlignment='Right' VerticalAlignment='Center' FontSize='18' FontWeight='Bold'><Hyperlink Tag='exit' TextDecorations='' ToolTip='Close current session and go back to user screen. Good Bye, good bye.'>Close current session</Hyperlink></TextBlock>"
"</Grid>"
"<Border Height='3' Background='#9ebbdd'/>"
"<Border Height='3' Background='White'/>"
"</StackPanel>"
"</Border>")
).c_str();
}
#include <iostream>
constexpr auto markup = markup_ribbon();
int main()
{
std::cout << markup << std::endl;
}
我知道这个问题是编译器+递归相关的,根本不是 boost::hana 的问题,但也许有一些调整、破解或我可以在 IDE 中调整的东西,所以这有效?
编译器正在放弃,因为您正在创建一个包含太多参数的模板。 Hana 字符串的表示形式是 hana::string<'<', '?', 'x', 'm',...>
,其中每个字符都是一个非类型模板参数。这是由 BOOST_HANA_STRING
宏中的一些技巧生成的。
我建议查看以下演示文稿,了解如何处理大型编译时字符串:Constexpr All the Things - Jason Turner、Ben Deane
除此之外,这里是一种可能的方法的基本示例,您可以根据自己的使用方式将其放入自己的宏中。
static constexpr char name[] = "really long string";
template <char const* str>
struct my_string {
static constexpr char const* value = str;
};
auto name_s = my_string<name>{};
static_assert(name_s.value[3] == 'l', "");
我正在使用 boost::hana::string
的编译时功能为 GUI 生成 xaml 标记字符串。
我正在使用配置为 C++17 语言的 VS2017,但有时字符串太长,我收到了来自编译器的下一条消息:
fatal error C1202: recursive type or function dependency context too complex
如果我从字符串中删除几个字符,一切正常,所以我猜是长度相关的。
下一段代码在 gcc 下的 coliru 中运行正常,但在 MSVS2017 中却惨遭失败:
注意:请注意,我已经删除了示例中的所有可配置和模板化变量,以便只关注问题。当然,不值得使用boost::hana之类的示例代码,只是一个最小的工作源。
#include <boost/hana/string.hpp>
constexpr auto markup_ribbon()
{
return (BOOST_HANA_STRING(
"<?xml version='1.0' encoding='iso-8859-1'?>"
"<Border VerticalAlignment='Top'>"
"<Border.Background>"
"<LinearGradientBrush StartPoint='0,0.2' EndPoint='0.8,0.8'>"
"<GradientStop Offset='0' Color='#cd0000'/>"
"<GradientStop Offset='0.75' Color='#fc999e'/>"
"<GradientStop Offset='1' Color='#e4ecf7'/>"
"</LinearGradientBrush>"
"</Border.Background>"
"<StackPanel Orientation='Vertical' TextBlock.FontFamily='Tahoma'>"
"<StackPanel.Resources>"
"<Style TargetType='Path'>"
"<Setter Property='Fill' Value='Blue'/>"
"<Style.Triggers>"
"<Trigger Property='IsMouseOver' Value='True'>"
"<Trigger.Setters>"
"<Setter Property='Fill' Value='Red'/>"
"</Trigger.Setters>"
"</Trigger>"
"</Style.Triggers>"
"</Style>"
"</StackPanel.Resources>"
"<Grid>"
"<Grid.ColumnDefinitions>"
"<ColumnDefinition Width='300'/>"
"<ColumnDefinition Width='*'/>"
"<ColumnDefinition Width='*'/>"
"<ColumnDefinition Width='50'/>"
"<ColumnDefinition Width='200'/>"
"</Grid.ColumnDefinitions>"
"<Image Margin='10' HorizontalAlignment='Left' VerticalAlignment='Center' Source='1'/>"
"<TextBlock Grid.Column='1' HorizontalAlignment='Left' VerticalAlignment='Center' FontSize='44' FontWeight='Bold' Foreground='#ffffff'>ASDF2021</TextBlock>"
"<Image Grid.Column='2' HorizontalAlignment='Left' VerticalAlignment='Top' Source='3'/>"
"<TextBlock Grid.Column='3' HorizontalAlignment='Right' VerticalAlignment='Center'><Hyperlink TextDecorations='' Tag='back' ToolTip='Back to administration screen. Back to administration screen.'><Path Stroke='Purple' StrokeThickness='2' Data='M12.981,9.073V6.817l-12.106,6.99l12.106,6.99v-2.422c3.285-0.002,9.052,0.28,9.052,2.269c0,2.78-6.023,4.263-6.023,4.263v2.132c0,0,13.53,0.463,13.53-9.823C29.54,9.134,17.952,8.831,12.981,9.073z'/></Hyperlink></TextBlock>"
"<TextBlock Grid.Column='4' Margin='0,0,30,0' HorizontalAlignment='Right' VerticalAlignment='Center' FontSize='18' FontWeight='Bold'><Hyperlink Tag='exit' TextDecorations='' ToolTip='Close current session and go back to user screen. Good Bye, good bye.'>Close current session</Hyperlink></TextBlock>"
"</Grid>"
"<Border Height='3' Background='#9ebbdd'/>"
"<Border Height='3' Background='White'/>"
"</StackPanel>"
"</Border>")
).c_str();
}
#include <iostream>
constexpr auto markup = markup_ribbon();
int main()
{
std::cout << markup << std::endl;
}
我知道这个问题是编译器+递归相关的,根本不是 boost::hana 的问题,但也许有一些调整、破解或我可以在 IDE 中调整的东西,所以这有效?
编译器正在放弃,因为您正在创建一个包含太多参数的模板。 Hana 字符串的表示形式是 hana::string<'<', '?', 'x', 'm',...>
,其中每个字符都是一个非类型模板参数。这是由 BOOST_HANA_STRING
宏中的一些技巧生成的。
我建议查看以下演示文稿,了解如何处理大型编译时字符串:Constexpr All the Things - Jason Turner、Ben Deane
除此之外,这里是一种可能的方法的基本示例,您可以根据自己的使用方式将其放入自己的宏中。
static constexpr char name[] = "really long string";
template <char const* str>
struct my_string {
static constexpr char const* value = str;
};
auto name_s = my_string<name>{};
static_assert(name_s.value[3] == 'l', "");