Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does C++11's decltype make clone unnecessary?

Tags:

c++

clone

c++11

The clone paradigm is used to make a copy of a derived class without casting down to the base class type. Unfortunately, clone must be implemented in each subclass (or with a mixin with CRTP).

Is there any chance that C++11's decltype makes this unnecessary?

I don't think the code below actually copies original, but simply points a reference to it. When I tried to use new decltype(*original), I get an error: error: new cannot be applied to a reference type.

Is clone still the way to go in C++11? Or is there some new way to use RTTI to copy a derived class object from a base class pointer?

#include <iostream>

struct Base
{
  virtual void print()
  {
    std::cout << "Base" << std::endl;
  }
};

struct Derived : public Base
{
  int val;
  Derived() {val=0;}
  Derived(int val_param): val(val_param) {}
  virtual void print()
  {
    std::cout << "Derived " << val << std::endl;
  }
};

int main() {
  Base * original = new Derived(1);
  original->print();

  // copies by casting down to Base: you need to know the type of *original
  Base * unworking_copy = new Base(*original);
  unworking_copy->print();

  decltype(*original) on_stack = *original;
  on_stack.print();
  return 0;
}
like image 693
user Avatar asked May 03 '12 02:05

user


3 Answers

decltype is a static construct. Like all C++ typing constructs, it cannot deduce the runtime type of an object. decltype(*original) is just Base&.

like image 176
Nicol Bolas Avatar answered Nov 05 '22 05:11

Nicol Bolas


decltype (as its name suggests) gives the declared type (static type) of the expression that it is applied to.

decltype(*original) is Base&, so your code will print

Derived 1
Base
Derived 1

but no copy will be made in the third case.

Clone (or some variant of the pattern) is still the way to go in C++11.

like image 41
Mankarse Avatar answered Nov 05 '22 06:11

Mankarse


decltype cannot and does not recover dynamic object type. It is a purely static construct.

There's no magic way to copy an object. You must call a constructor of its exact final dynamic type somewhere.

like image 3
n. 1.8e9-where's-my-share m. Avatar answered Nov 05 '22 05:11

n. 1.8e9-where's-my-share m.