0
#include <string>

struct S
{
    std::string s_;

    std::string_view get() const &
    {
        return s_;
    }

    std::string_view get() const && = delete;
};

//  I can't change this
struct T
{
    T(std::string_view const sv);  //  does something safe with sv
};

//  I can't change this
void f(std::string_view const &);

void g()
{
    f(S{}.get());  //  should compile
    T t(S{}.get());  //  should compile
    std::string_view sv = S{}.get();  //  should not compile
}

Is there way to use ref qualifiers without hindering usability as in the case above? In essence, it should prevent unsafe usage, but allow safe usage. I can wrap f which does this, but it is unnecessary verbosity

zrb
  • 851
  • 7
  • 16
  • you should include the compiler error message you do get from the code in the question – 463035818_is_not_an_ai Dec 07 '22 at 07:40
  • I don't believe so. `S{}.get()` is either allowed or not. *Where* it's used makes no difference. – super Dec 07 '22 at 07:41
  • one approach is to return a proxy that can be converted to the actual desired type, but I dont see how it can be `// should compile` and at the same time `// should not compile` – 463035818_is_not_an_ai Dec 07 '22 at 07:43
  • 1
    `std::string_view const & get() const && = delete;` means that you don't want `S{}.get()` to be compiled. But then your code `f(S{}.get()); // should compile` contradicts this. – Jason Dec 07 '22 at 07:45
  • Possibly related: [Forcing class instances to be const](https://stackoverflow.com/q/41793183/580083). – Daniel Langr Dec 07 '22 at 07:47
  • It is a contradiction. But is there a way to allow the safe usage while disallowing unsafe usage? Wrapper classes and functions do the trick, but was trying to avoid that – zrb Dec 07 '22 at 07:51

1 Answers1

0

Is there way to use ref qualifiers without hindering usability as in the case above?

No, because when you wrote std::string_view get() const && = delete; you're essentially(implicitly) saying that S{}.get() should not be compiled. But then later in the code you're writing f(S{}.get()); // should compile which contradicts the above code.

Basically, whether or not S{}.get() can be used is decided by the presence of the std::string_view get() const && = delete;.

Jason
  • 36,170
  • 5
  • 26
  • 60
  • But is there a way to differentiate the 2 types of usage? I guess not. I'll go with a wrapper for `f` – zrb Dec 07 '22 at 08:04
  • @zrb Basically, `S{}.get()` follow the same rule that it is not allowed in any evaluated context because you've written `std::string_view get() const && = delete;`. Not possible to differentiate. – Jason Dec 07 '22 at 08:05