Search code examples
c++pass-by-referenceassertrvalue-reference

rvalue Reference not matching


I have this exercise in which we try various combinations of rvalue and lvalue references using a template class, I am getting two assertion errors; if someone could guide.

#include <assert.h>

typedef int& IntLRef;
typedef IntLRef& IntLLRef;
typedef IntLRef&& IntLRRef;

typedef int&& IntRRef;
typedef IntRRef& IntRLRef;
typedef IntRRef&& IntRRRef;

template<typename T, typename U>
struct IsSameType
{
  static const bool value = false;
};

template<typename T>
struct IsSameType <T, T>
{
    static const bool value = true;
};
static_assert(IsSameType<IntLRef, IntLLRef>::value, "LRef DIF LLRef"); static_assert(IsSameType<IntLRef, IntLRRef>::value, "LRef DIF LRRef"); static_assert(IsSameType<IntLLRef, IntLRRef>::value, "LLRef DIF LRRef");

static_assert(IsSameType<IntRRef, IntRLRef>::value, "RRef DIF RLRef"); static_assert(IsSameType<IntRRef, IntRRRef>::value, "RRef DIF RRRef"); static_assert(IsSameType<IntRLRef, IntRRRef>::value, "RLRef DIF RRRef");

int main();

I am getting assertion error :

rvalue_ex3.cpp:34:48: error: static assertion failed: RRef DIF RLRef
   34 |   static_assert(IsSameType<IntRRef, IntRLRef>::value, "RRef DIF RLRef");
      |                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~
rvalue_ex3.cpp:36:49: error: static assertion failed: RLRef DIF RRRef
   36 |   static_assert(IsSameType<IntRLRef, IntRRRef>::value, "RLRef DIF RRRef");
      |                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~
akm009@a

I need to make modfications to assert it as true and understand why it is failing


Solution

  • This is called reference collapsing:

    It is permitted to form references to references through type manipulations in templates or typedefs, in which case the reference collapsing rules apply: rvalue reference to rvalue reference collapses to rvalue reference, all other combinations form lvalue reference

    (emphasis added)

    Which means that IntRRef which is int&& is not the same as IntRLRef because the latter is defined as IntRRef& which is an lvalue reference to an rvalue reference and thus collapses to an lvalue reference: int&.