0

Below is a partial class SafeString (omitting not related methods):

class SafeString
{
private:
    char* _str = nullptr;
public:
    operator std::string() const {
        return { _str };
    }

    friend std::ostream& operator<<(std::ostream& os, const SafeStringInternal& ss) {
        return os << ss.c_str();
    }

    const char* c_str() const noexcept {
        return _str;
    }
}

I try to pass an instance:

SafeString name;

To a function:

FrameInput(std::string& name);

But the compiler is unable to distinguish the implicit conversion.

When I change the variable and function signature, adding const, the compiler passes.

const SafeString name;
const FrameInput(std::string& name);

What changes do I have to do in the SafeString class to support both const and non-const variables for const and non-const function parameter, respectively?

Andrey
  • 853
  • 9
  • 27
  • 1
    What do you mean by "compiler is unable to distinguish the implicit conversion"? Can you copy and paste the actual error? Also, show how do you want do use that operator (molbdnilo is probably onto something). – Yksisarvinen Aug 13 '22 at 15:08
  • 5
    The issue is that you can't bind a non-const reference to a temporary object. (Also, implicit conversions are evil.) – molbdnilo Aug 13 '22 at 15:10
  • Also, that conversion will cause problems with a default `SafeString`, which isn't very safe at all. – molbdnilo Aug 13 '22 at 15:11
  • @molbdnilo Where is a temporary object here? Could you refer me to some reading, please? – Andrey Aug 13 '22 at 15:12
  • @molbdnilo Sure, it's not safe. It is only an abstract example to make my question clear. – Andrey Aug 13 '22 at 15:13
  • @Andrey The `std::string` returned from your conversion function is a temporary. (Why does `MicrVsFrameInput` want a non-const string in the first place?) – molbdnilo Aug 13 '22 at 15:14
  • @Andrey Adding bugs does not clarify anything. – molbdnilo Aug 13 '22 at 15:18
  • @molbdnilo I have a big code base with a class, used in many places. This class has a std::string attribute that I need to replace with SafeString (in debug mode only). Some functions in a code base have const parameters, some do not. I want to make this type swap without changing the other code. – Andrey Aug 13 '22 at 15:19
  • 2
    @Andrey This is explained in any beginner level [C++ book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). In particular, a nonconst lvalue reference cannot bind to an rvalue. In your example the result of calling the conversion operator is an rvalue of type `string` which cannot bind to the parameter of type `string&`. – Jason Aug 13 '22 at 15:23
  • @Andrey You have to change the other code or rethink `SafeString` from scratch (or, most likely, do both). – molbdnilo Aug 13 '22 at 15:39

0 Answers0