0

I wrote an operator function that returns std::stringstream when suffix _f appears.

#include <iostream>
#include <sstream>
#include <utility>

static std::stringstream&& operator "" _f(const char* const s, const size_t _) {
    return std::move(std::stringstream() << s);
}

int main() {
    const auto s = "Number: "_f << 10 << '\n';
    std::cout << s.str();
    return 0;
}

However, when I run this I get a runtime exception: "Access violation reading location ...".

Can you please tell me, where's the mistake in my code?

sanitizedUser
  • 1,723
  • 3
  • 18
  • 33
  • 3
    Your function returns a reference to a temporary. The temporary is destroyed as soon as the function returns, and the caller attempts to use a now-dangling reference, whereupon the program exhibits undefined behavior. – Igor Tandetnik Oct 09 '21 at 15:21
  • 1
    Additionally, one should rarely return references from a function (and you do exactly that, return by value instead) and one should almost never `return std::move` – yeputons Oct 09 '21 at 15:22
  • 1
    @yeputons C++ streams can't be passed around by value, though. They don't support copy semantics, only move semantics – Remy Lebeau Oct 09 '21 at 16:05

1 Answers1

3

The operator returns a reference to a temporary std::stringstream object inside the function, resulting in a dangling reference. You should return std::stringstream directly.

static std::stringstream operator "" _f(const char* const s, const size_t _) {
    return std::stringstream() << s;
}
sanitizedUser
  • 1,723
  • 3
  • 18
  • 33
康桓瑋
  • 33,481
  • 5
  • 40
  • 90
  • 1
    Note that this will only work if the compiler employs RVO (ie, [copy elison](https://en.cppreference.com/w/cpp/language/copy_elision)) to optimize away a copy operation on return, as C++ streams can't be copied, only moved. – Remy Lebeau Oct 09 '21 at 16:07
  • 3
    This is a C++17 question, so I think copy elision is guaranteed. – 康桓瑋 Oct 09 '21 at 16:09
  • perhaps so. However, user-defined literals were introduced in C++11. And it is not uncommon for users to tag questions with multiple C++ versions, or even C++ versions that are not actually using, just to get more eyes on them (I'm not saying that happened this time). Someone may later come across this answer and try to use it in a scenario where copy elison is not used, and then wonder why it doesn't work. Hence my earlier comment. – Remy Lebeau Oct 09 '21 at 17:12