由于 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,2.269c0,2.78-6.023,4.263-6.023,4.263v2.132c0,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,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 的问题,但也许有一些调整、hack 或我可以在 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',"");

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...