带有std :: quoted的Visual Studio中的错误

时间:2018-04-26 16:47:18

标签: c++ visual-studio-2017 language-lawyer

确保它确实是一个错误,而不是我可能误解了std::quoted的功能

以下代码应该在我看来用双引号转义双引号然后将它们转换回原始字符串:

#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>

int main()
{
    std::string s = R"(something"something)";
    std::cout << "Original: \t" << s << std::endl;

    std::ostringstream oss;
    oss << std::quoted(s, '"', '"');
    std::string s1 = oss.str();
    std::cout << "Quoted: \t" << s1 << std::endl;

    std::istringstream iss(s1);
    std::string s2;
    iss >> std::quoted(s2, '"', '"');
    std::cout << "Unquoted: \t" << s2 << std::endl;

    return 0;
}

预期产出:

Original:   something"something
Quoted:     "something""something"
Unquoted:   something"something

然而,这是我在VS2017 15.6.6中获得的:

Original:   something"something
Quoted:     "something""something"
Unquoted:   something

有人能证实这是一个错误吗?

更新

大家好消息。 ticket I filed with MS标记为fixed

1 个答案:

答案 0 :(得分:5)

在对这个问题进一步研究后,我想回答我自己的问题。感谢@Justin和@MatteoItalia的深刻见解。简而言之,这不是一个错误,而是一个未定义的行为,因为VC ++似乎遵循standard到点,而其他编译器采取自由来以自己的方式解释它,因为没有严格的指导如何处理delim == escape的案例,此paragraph无法解释:

  

在到达未转义的delim字符或!in之前,提取   来自in的字符并将它们附加到s,除非转义为   到达,忽略它并将下一个字符附加到s。

这正是VC ++发生的事情,"被解释为未转义的delim字符而不是转义字符后的第一个双引号something,它终止了例程。 IMO需要澄清,例如:如果找到转义字符,请检查它是否后跟delim字符,如果是,则丢弃转义字符。我认为这是original proposal

我已经在MS bug跟踪器上提交了report,但对修复TBH没有多大希望。然后我找到this ticket @Barry建议使用GCC中的现有实现herehere,这正是我所做的。

这对我有用,但如果您有任何疑虑或建议,请分享。