【问题标题】:Deciphering C++ template error messages解密 C++ 模板错误消息
【发布时间】:2010-09-08 01:25:06
【问题描述】:

当人们说 C++ 的错误消息在模板方面非常糟糕时,我真的开始理解他们的意思了。我已经看到了像函数与原型不匹配这样简单的事情的可怕的长错误。

有什么技巧可以破解这些错误吗?

编辑:我同时使用 gcc 和 MSVC。他们看起来都很糟糕。

【问题讨论】:

    标签: c++ templates compiler-errors


    【解决方案1】:

    您可以尝试使用以下工具让事情变得更理智:

    http://www.bdsoft.com/tools/stlfilt.html

    【讨论】:

      【解决方案2】:

      我绝对不能。小错误会爆发成一页又一页的不可读的垃圾。通常在清晨,在喝咖啡之前。 :(

      我唯一的建议是深呼吸,从顶部开始,尝试解析重要的信息。 (我知道,说起来容易做起来难,对吧?)。

      【讨论】:

        【解决方案3】:

        正如@nsanders 所说STLFilt 是一个很好的解决方案。一个自制的 STLFilt(当您不想麻烦安装 Perl 时)是在编辑器中复制错误消息并开始替换部分错误,直到它变得(更)易于管理。

        例如

        s/std::basic_string<char,std::char_traits<char>,std::allocator<char>>/string/g 
        

        用不那么令人讨厌的术语来说,这意味着:

        替换:

        std::basic_string<char,std::char_traits<char>,std::allocator<char>>
        

        与:

        string
        

        【讨论】:

        • 这比听起来更有用。不要为人脑的信息过载限制感到尴尬——那里的人之间的差异比他们愿意承认的要少。我们可以一次匹配大约相同数量的模式——诀窍是逐渐学会匹配更大的模式。
        【解决方案4】:

        一些编译器比其他编译器提供更好的消息。你用的是什么编译器?话虽如此,他们都很糟糕。 C++0X 将解决这个问题的大部分(参见concepts),但该标准要到 2009 年才会发布,广泛的支持可能会更晚:-(

        【讨论】:

        • -1 他们仍然无法破译;也许不像以前那样难以辨认,但仍然很可怕!
        • 是的,我现在正在努力解决一个问题。它们很难在视觉上解析!
        • Concepts 没有进入 C++11。
        • 8 年后,概念现在在 C++17 中。他们将如何帮助破译模板错误?
        【解决方案5】:

        至少在 Visual Studio 中,Output Build 窗口而不是错误列表中提供了更多信息。我在错误列表状态中遇到了一个模板错误,“无法将 Foo 转换为 Foo”。在输出窗口中的实际错误后面有几行帮助我破译了实际问题。

        【讨论】:

          【解决方案6】:

          虽然它是一个旧帖子,但这可能对其他偶然发现此帖子的人有所帮助。

          我遇到了完全相同的问题,在我的情况下,错误甚至无法再打印到屏幕上,因为它们太长了。所以我将它们转储到一个文本文件中并尝试使用文本编辑器进行一些基本搜索,而不是通过文件进行 grep'ing,其中一些可能高达 20 MB(对于 errors 来说还不错) .大多数错误都会重复,因为我是并行编译的,所以这是另一个大问题。

          由于我对这种方法感到厌倦(而且效率也不高),我开发了一个小型帮助程序,我可以将它直接链接到我的编译器工具链中,以便编译器生成的任何输出都可以基于格式在 json 文件中定义的一些规则。该程序可以在这里找到:https://github.com/tomrobin-teschner/dotify

          共有三个基本功能:

          • 如果编译器的当前输出(行)包含某个字符串,则不要打印它
          • 只打印包含关键字(可以着色)的特定行
          • 如果涉及模板,请删除 括号之间的内容并用点替换它们。例如,MyClass&lt;std::vector&lt;double&gt;, std::array&lt;double, 3&gt;&gt; 将被简单地替换为 MyClass&lt;...&gt;

          完整的错误消息仍然存储在日志文件中(如果需要更详细的信息,以后可以使用),解析器只处理打印到控制台的输出。

          调用解析器的命令是

          /path/to/program | tee log | /path/to/parser -f /path/to/inputFile.json

          /path/to/program 是要执行的程序(并且应该从中格式化输出) /path/to/parser -f /path/to/inputFile.json,解析器的位置,-f 标志指定输入文件(json 格式),对于一个非常简单的情况,它可能如下所示:

          {
            "ignoreCompleteLineIfItContainsSubstring" : [
              "should be suppressed"
            ],
            "ignoreContentBetweenDelimiter" : [
              {
                "startingDelimiter" : "<",
                "endingDelimiter" : ">",
                "replaceContentBy" : "..."
              }
            ],
            "styleLineContainingKeywords" : [
              {
                "keyword" : "error",
                "removeDuplicates" : true,
                "applyStyle" : "onKeyword",
                "color" : "red",
                "style" : "bold"
              }
            ]
          }
          

          可在项目网站 (https://github.com/tomrobin-teschner/dotify) 上找到完整的选项列表和说明

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-10-07
            • 1970-01-01
            • 1970-01-01
            • 2021-01-22
            • 1970-01-01
            • 1970-01-01
            • 2011-04-12
            • 1970-01-01
            相关资源
            最近更新 更多