In C++, memory and CPU/GPU management are very important and the compiler is amazingly using them well in templates, classes, and objects. Every declaration and usage of any bits may cause a lot of heavy calculations, memory usage, and high CPU/GPU usage. Using copy and move types in templates is very important when you develop a professional app. In this post, we explain how you can use non-copyable movable types in C++ templates.
Understanding non-copyable but movable types in C++ templates
In C++, types that are not copyable, such as ones that use unique_ptr, can be made movable. Although they cannot define assignment operators, they can implement move functions and swap functions, since these do not require copying when rvalue references are used. A sort function could be developed, since it only requires swapping, not copying.
For instance, consider this Tx function that takes one argument:
1 2 3 4 5 6 7 |
template <class T, class U> T Tx(const U& u) { return new T(u); } |
However, a compiler error occurs when a T
is used whose constructor’s parameter is a non-const reference. You can fix this case by removing const
from the definition:
1 2 3 4 5 6 7 |
template <class T, class U> T Tx(U& u) { return new T(u); } |
However, the previous example now fails: This causes an error, because the value causes the template argument to be matched to int &, but this does not bind to the rvalue .
This can be remedied by defining a factory function for each case of const and non-const. This is however problematic, because the number of functions needed increases exponentially with the number of arguments.
Now, let’s see how we can do this.
Is there a simple example of non-copyable but movable types in C++ templates?
If you make the argument an rvalue reference, you can simplify the situation:
1 2 3 4 5 6 7 |
template <class T, class U> T factory(U&& u) { return new T(factory<U>(u)); } |
Now the argument u binds to both rvalues and lvalues. The forward function returns an rvalue or lvalue, exactly as it was passed. It can be defined in this way:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
template <class U> struct identity { typedef U type; }; template <class U> U&& forward(typename identity<U>::type&& u) { return u; } |
Is there a full example of non-copyable but movable types in C++ templates?
Here is a full C++ example that combines all of the above.
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 |
#include <iostream> template <class T, class U> T Tx(const U& u) { return new T(u); } template <class T, class U> T Tx(U& u) { return new T(u); } template <class T, class U> T factory(U&& u) { return new T(factory<U>(u)); } template <class U> struct identity { typedef U type; }; template <class U> U&& forward(typename identity<U>::type&& u) { return u; } int main() { } |
For more information on this feature, check this link and see Rvalue references for *this Proposal document.
C++ Builder is the easiest and fastest C and C++ IDE for building simple or professional applications on the Windows, MacOS, iOS & Android operating systems. It is also easy for beginners to learn with its wide range of samples, tutorials, help files, and LSP support for code. RAD Studio’s C++ Builder version comes with the award-winning VCL framework for high-performance native Windows apps and the powerful FireMonkey (FMX) framework for cross-platform UIs.
There is a free C++ Builder Community Edition for students, beginners, and startups; it can be downloaded from here. For professional developers, there are Professional, Architect, or Enterprise version.
Design. Code. Compile. Deploy.
Start Free Trial
Free C++Builder Community Edition