Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type of member variable should depend on constructor argument's type

I try to define a class A as follows:

template< typename T >
class A
{
  public:
    A( T elem )
      : _elem( elem )
    {}

  private:
    TYPE _elem; // "TYPE" should be either "T" in case "elem" is an r-value or "T&" in case "elem" is an l-value.
};

Here, I want _elem to have either the type T in case that the constructor's argument elem is an r-value or the type T& in case elem is an l-value.

Does anyone know how this can be implemented?

like image 362
abraham_hilbert Avatar asked Nov 11 '16 10:11

abraham_hilbert


1 Answers

Until we get template argument deduction for class templates, you'll need to use a helper function for this:

template <typename T>
auto make_a (T&& elem) {
    return A<T>{std::forward<T>(elem)};
}

This uses a forwarding reference to deduce whether the argument is an lvalue or rvalue and constructs the A by perfectly forwarding the argument. Taking int as an example, if an lvalue is passed, T will be int&, and if an rvalue is passed, T will be int.

Your A template should just look like this:

template< typename T >
class A
{
  public:
    A( T elem )
      : _elem( elem )
    {}

  private:
    T _elem;
};

You could make make_a a friend and make the constructor private if you only want to allow construction from the factory method.

like image 156
TartanLlama Avatar answered Nov 05 '22 20:11

TartanLlama