jeudi 14 septembre 2023

Using add_rvalue_reference and add_lvalue_reference with template types

My small test program is aimed at testing the use of add_rvalue_reference and add_lvalue_reference for obtaining references of template types.

//test.h

#include<cstddef>
#include <type_traits>

using std::size_t;
using std::add_lvalue_reference;
using std::add_rvalue_reference;

template<class T>
  struct unref {typedef T type;};
template<class T> 
  struct unref<T&>{typedef T type;};
template<class T> 
  struct unref<T&&>{typedef T type;};

template<typename T>
class A{
   public:
   constexpr A(T);
   constexpr ~A();
   private:
   A()=delete; 
   A(const A&)=delete;
   A& operator=(const A&)=delete;
   private:
   T elem;
};

template<typename T, size_t N>
using arrayofAs = A<T>[N];

template<typename T, size_t N>
using lvrefarrayofAs = add_lvalue_reference<arrayofAs<T>>;

template<typename T, size_t N>
using rvrefarrayofAs = add_rvalue_reference<arrayofAs<T>>;

template<typename T> constexpr A<T>::A(T elem):elem(elem){}
template<typename T> constexpr A<T>::~A(){}

//main.cpp

#include "test.h"
#include <iostream>

using std::is_same;
using std::cout;
using std::endl;

int main (){

  cout << is_same<unref<lvrefarrayofAs>, arrayofAs>::value << endl;  
  cout << is_same<unref<rvrefarrayofAs>, arrayofAs>::value << endl;  

  return 0;
}

To begin with, I get the following compilation error in test.h:

In file included from main.cpp:1:
test.h:35:55: error: wrong number of template arguments (1, should be 2)
   35 | using lvrefarrayofAs = add_lvalue_reference<arrayofAs<T>>;
      |                                                       ^
compilation terminated due to -Wfatal-errors.

My understanding is that the template array size is not part of its type (please correct me if I am mistaken on this), so not sure why the compiler insists on specifying the template non-type paramter?

The error disappears after I rewrite the two related using declarations in the original code as shown below:

    template<typename T, size_t N>
    using lvrefarrayofAs = add_lvalue_reference<arrayofAs<T,N>>;
    
    template<typename T, size_t N>
    using rvrefarrayofAs = add_rvalue_reference<arrayofAs<T,N>>;

But now I get the following error in main.c:

main.cpp: In function ‘int main()’:
main.cpp:21:39: error: type/value mismatch at argument 1 in template parameter list 
for ‘template<class T> struct unref’
   21 |   cout << is_same<unref<lvrefarrayofAs>, arrayofAs>::value << endl;
      |                                       ^
compilation terminated due to -Wfatal-errors.

I presume the type of argument 1 passed to is_same<> template is valid, based on the using declarations for both unref<T&>and lvrefarrayofAs in test.h.

So why does the compiler report this error?

TIA

Aucun commentaire:

Enregistrer un commentaire