0

I have this code in VS2019, which compiled and ran fine under C++14:

class Parser
{
    void Parse(istream& input)
    { 
        // Do the parsing
    }
}

class ParserTests
{
    void TestTheParser()
    {
        constexpr auto TheText = "Some text to parse";

        auto parser = Parser{};

        // Create a temporary stringstream around the text to parse:
        // This line compiles and runs fine in VS2019 with C++14 language
        parser.Parse(stringstream{ TheText });
    }
}

I recently switched my code to C++20, and I suddenly get the following compiler error when I call parser.Parse():

cannot convert argument 1 from std::stringstream to std::istream&

If I change my test code to use a real variable instead of an inline temporary:

// Seat the stringstream to a variable, before calling Parse
auto strm = stringstream{ TheText };
parser.Parse(strm);

then my code once again starts working.

Is this a bug in Visual Studio's support of C++20? Or is this a new language restriction that I do not yet understand? I have a lot of test code written like this, and I'm a bit annoyed at the prospect of changing every single one.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
BTownTKD
  • 7,911
  • 2
  • 31
  • 47
  • 1
    This is an MSVC extension (which relaxes rules imposed by the C++ standard) : https://learn.microsoft.com/en-us/cpp/build/reference/zc-referencebinding-enforce-reference-binding-rules?view=msvc-160 – user2407038 Jun 18 '21 at 15:15
  • Why not `void Parse(const istream& input)`? –  Jun 18 '21 at 15:25
  • 3
    `I'm a bit annoyed at the prospect of changing every single one.` Take this as a lesson to not use language extensions. Compilers typically have an option to at least warn when you use them - or fail compilation entirely. I would expect that to apply to MSVC as well. – eerorika Jun 18 '21 at 15:30
  • According to [this](https://learn.microsoft.com/en-us/cpp/build/reference/za-ze-disable-language-extensions?view=msvc-160) you can at least disable extensions with C with `/Za`, but for some reason it also says this can cause unexpected behavior with C++ and isn't recommended. – mediocrevegetable1 Jun 18 '21 at 15:35
  • 2
    Could change `void Parse(istream& input)` to `void Parse(istream&& input)`. Or have it just be a thunk to the other `void Parse(istream&& input) { Parse(input); }` – Eljay Jun 18 '21 at 15:39

0 Answers0