Is this a good implementation ? ( factory pattern + forwarding )

I'm trying to get into meta-programming techniques, with the new C++11 we now get the ability to "forward" ( which is basically a cast for what I know ) the construction of the object so the lazy people are happier than ever and they don't have to write a lot of boiler plate stuff.

So my result is

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <iostream>
#include <utility>
#include <cstdint>

class T {
public:

  T() : u32(42) {
    std::cout << "default ctor"
              << "\n";
  }

  T(const T &t) {
    this->u32 = t.u32;
    std::cout << "copy ctor"
              << "\n";
  }

  T(T &&t) {
    this->u32 = t.u32;
    t.u32 = 0;
    std::cout << "move ctor"
              << "\n";
  }

  uint32_t u32;
};

template <class T> T buildT(T t) { return T(std::forward<T>(t)); }

int main() {
  std::cout << buildT(T()).u32 << "\n";
  std::cout << "--\n";
  T a;
  std::cout << "--\n";
  std::cout << buildT(a).u32 << "\n";
  std::cout << "--\n";
  std::cout << buildT(std::move(a)).u32 << "\n";
  return (0);
}


First of all is this a good implementation that reflects the factory pattern and perfect forwarding ?

Assuming that my code reflects what I think it reflects:
- the point of the factory pattern is to template the type that is passed to the constructor ?
- it's possible to avoid calling a constructor 2 times and improve my buildT ?
- what are other possible applications for std::forward ?
You might want to read this (perfect forwarding is covered in section 8):
http://thbecker.net/articles/rvalue_references/section_01.html
@JLBorges can you expand a little more ? I will read that, but I'm curious about what you guys think. The part with rvalues, the perfect forwarding is something that I'm still experimenting with, right now I'll stick with just the use of forward and the factory pattern for this question, at least for the moment.
> template <class T> T buildT(T t)

T is passed by value; the issue of perfect forwarding does not arise.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>

struct A
{
    A( int i ) : v(i) {}

    A( const A& that ) : v(that.v) { std::cout << "A::copy_constructor one \n" ; }

    A( A& that ) : v(that.v) { std::cout << "A::copy_constructor two\n" ; }

    A( A&& that ) noexcept : v(that.v) { std::cout << "A::move_constructor\n" ; }

    const int v ;
};

template < typename T > T build( T&& t ) // rvalue reference
{ return T( std::forward<T>(t) ) ; }

A foo() { A a(400) ; return a ; }

int main()
{
    A a1(100) ;
    const A a2(200) ;

    // forwarded as A&
    A a3 = build(a1) ; // A::copy_constructor two
    std::cout << a3.v << '\n' ;

    // forwarded as const A&
    A a4 = build(a2) ; // A::copy_constructor one
    std::cout << a4.v << '\n' ;

    // forwarded as A&&
    A a5 = build( A(300) ) ; // A::move_constructor
    std::cout << a5.v << '\n' ;

    // forwarded as A&&
    A a6 = build( foo() ) ; // A::move_constructor
    std::cout << a6.v << '\n' ;
}

http://coliru.stacked-crooked.com/a/5a7551c8fe304212
Topic archived. No new replies allowed.