3

I want my function to take a lvalue reference and absolutely not a rvalue or temporary or whatever.

This is my function:

template<class T>
void foo(T& value) {}

// Imagine I have a class Foo
struct Foo
{ 
   int a;
   int b;
};

When I call foo(Foo{1, 2}), first, it compiles even if I asked for a lvalue reference, and second, it doesn't work because foo stores the address of the passed value, so I get garbage when I read it later.

How to force foo to take a lvalue reference?

JeJo
  • 30,635
  • 6
  • 49
  • 88
Jojolatino
  • 696
  • 5
  • 11
  • Look at https://stackoverflow.com/questions/50852470/how-to-force-a-function-to-only-accept-an-lvalue-reference-parameter – alex_noname Jun 24 '20 at 20:28
  • 4
    With your given code snippets `foo(Foo(1, 2))` does not compile. – Werner Henze Jun 24 '20 at 20:29
  • 1
    https://learn.microsoft.com/en-us/cpp/build/reference/zc-referencebinding-enforce-reference-binding-rules?view=vs-2019 – cpplearner Jun 24 '20 at 20:29
  • What compiler are you using? VS2019 emits a `warning C4239: nonstandard extension used: 'argument': conversion from 'Foo' to 'T &'` or an `error C2664: 'void foo(T &)': cannot convert argument 1 from 'Foo' to 'T &'`, depending on if languages extensions are enabled or disabled. – Werner Henze Jun 24 '20 at 20:31
  • That doesn't work at all: See [on coliru](//coliru.stacked-crooked.com/a/65fa816c3f20d1cf) – Deduplicator Jun 24 '20 at 20:31
  • I fixed the compile error – Jojolatino Jun 24 '20 at 20:33
  • @Kiosto Still it can't be: https://godbolt.org/z/oyhayR, unless you have MSVS: https://godbolt.org/z/PAML25, with non-standard extensions on. – JeJo Jun 24 '20 at 20:36

1 Answers1

6

First of all, the given code will not compile by default in GCC and Clang, only in MSVC with non-standard extensions.

If you want to make sure that foo() does not accept an rvalue, just delete that overload:

template<class T>
void foo(T&& value) = delete;
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
JeJo
  • 30,635
  • 6
  • 49
  • 88
  • That’s a universal reference, so it triggers regardless of value category. You’re relying on partial ordering to prefer the lvalue-reference choice; better would be to constrain the deleted function template so that it doesn’t outcompete normal functions that require conversions. – Davis Herring Jun 25 '20 at 02:27