C++ is a highly evolved and mature programming language. The C++ language has a great set of choices of modern C++ tool sets and compilers all of which come with a lot of utilities, GUI components, and libraries. C++11 was a big step for functional programming with C++. It has brought many other features like automatic type deduction (auto
), lambda expressions, and decltype
features. In this post, we explain what decltype
is and how to use it with today’s modern C++.
Table of Contents
What is the decltype type specifier in C++?
The decltype
keyword and operator represents the type of a given entity or expression. This feature is one of the C++11 features added to compilers (including BCC32 and other CLANG compilers). In a way you are saying “I am declaring this variable to be the same type as this other variable“.
Here is the Syntax:
1 2 3 |
decltype ( expression or entity ) |
Note that, C++11 brings us the C++11 Standard Library and Threading Library with a lot of new features like Lambda expressions, automatic type deduction (auto
) and decltype
(e), uniform initialization syntax (mapping etc.), deleted
and defaulted
functions, uniform initialization syntax, Rvalue
References, new smart pointer classes, and new C++ algorithms <algorithm>. Most of these features enable C++ to be a functional programming language. Typical C++ functions for use in functional programming include: map
, filter
, and reduce
. There are also the functions std::transform
, std::remove_i
f, and std::accumulate
.
Lambdas are one of the great additions to C++11 and has changed the way we write C++ code. In general, most programmers argue that modern C++ code should be using lambdas because it allows us to create in-place anonymous functions which in turn makes C++ a Functional Programming Language.
Is there a simple example of how to use the decltype type specifier in C++?
It’s easier to explain decltype
with an example. Let’s assume there is a variable c
and you don’t know its type. You can use decltype
. Here is a simple example.
1 2 3 4 |
char c; decltype(c) c2; // char c2; |
here is more detailed example:
1 2 3 4 5 6 7 8 9 10 11 |
char c='A'; int i = 10; float f = 9.81; std::string s = "this is string"; decltype(c) c2; // char c2; decltype(i) i2; // int i2; decltype(f) f2; // float f2; decltype(s) s2; // string s2; |
in this example only types of new variables are the same as the old ones. Values of new variables are their default values, values are not copied. In other words it is only used to declare types of that given type.
Is there rules about decltype type specifier in C++ ?
Here are the rules for evaluating decltype
.
- If
e
is an identifier expression or is accessing a class member,decltype(e)
is the type of the identifier or accessor designated bye
. If there is no such thing, or ife
is the name of a set of overloaded functions, so there is ambiguity,decltype(e)
is invalid. - Otherwise, if
e
is a function call or invokes an overloaded operator,decltype(e)
is the type returned by the function. - Otherwise, if
e
is an lvalue,decltype(e)
is a reference toT (T&)
, where T is the type ofe
. - If none of the other cases apply,
decltype(e)
is the type ofe
.
Here e
is a variable that it can be a char
, int
, float
, double
, long long int
, string
, a member of a struct
or class
object, etc.
Is there a full example of how to use the decltype type specifier in C++?
Here is a simple example that uses decltype
to declare new variables.
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 42 43 44 45 |
#include <iostream> #include <string> int main() { char c='A'; int i = 10; float f = 9.81; std::string s = "this is string"; std::cout << c << "," << i << "," << f << "," << s << "," << std::endl; // lets use decltype to declare new variables decltype(c) c2; // char c2; decltype(i) i2; // int i2; decltype(f) f2; // float f2; decltype(s) s2; // string s2; std::cout << c2 << "," << i2 << "," << f2 << "," << s2 << "," << std::endl; //lets use our new variables c2 = c + 1; i2 = i + 1; f2 = f + 0.02; s2 = s + " two"; std::cout << c2 << "," << i2 << "," << f2 << "," << s2 << "," << std::endl; system("pause"); return 0; } |
Here is another full example that uses decltype
to define members of other types like functions, structs, classes, etc,
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 42 43 44 45 46 47 48 49 50 51 52 53 54 |
#include <iostream> const int* foo() { return new int[0]; } struct A { double value; }; class B { int value; public: const A* function() { return new A(); } }; double GetValue(int one); long int GetValue(double d); template<class T> class C { public: T* value; }; int main() { double e; const char *pch; char ch; A* a = new A(); B* b = new B(); C<B> *c = new C<B>(); decltype(pch) var1; // type is const char* decltype(ch) var2; // type is char decltype(a) var4; // type is A* decltype(a->value) var5; // type is double decltype((a->value)) var6 = e; // type is const double& decltype(foo()) var7; // f is const int* decltype(b->function()) var8; // type is const A* decltype(c->value) var9; // type is B* decltype(GetValue(e)) var10; // well-formed, the declaration is not } |
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 versions of C++ Builder and there is a trial version you can download from here