From 6c831c4e66f33d4ed83740e97e210337d39a5955 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ciro=20Santilli=20=E5=85=AD=E5=9B=9B=E4=BA=8B=E4=BB=B6=20?= =?UTF-8?q?=E6=B3=95=E8=BD=AE=E5=8A=9F?= Date: Tue, 20 Oct 2020 02:00:01 +0000 Subject: [PATCH] decltype --- README.adoc | 14 ++++++++ userland/cpp/decltype.cpp | 69 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 userland/cpp/decltype.cpp diff --git a/README.adoc b/README.adoc index 6e8030b..4a85e93 100644 --- a/README.adoc +++ b/README.adoc @@ -20518,6 +20518,20 @@ link:userland/cpp/static_dynamic_reinterpret_cast.cpp[] https://stackoverflow.com/questions/332030/when-should-static-cast-dynamic-cast-const-cast-and-reinterpret-cast-be-used/60414256#60414256 +[[cpp-compile-time-magic]] +==== C++ compile time magic + +[[cpp-decltype]] +===== C++ `decltype` + +link:userland/cpp/decltype.cpp[] + +C++11 keyword. + +Replaces decltype with type of an expression at compile time. + +More powerful than `auto` as you can use it in more places. + === POSIX Programs under link:userland/posix/[] are examples of POSIX C programming. diff --git a/userland/cpp/decltype.cpp b/userland/cpp/decltype.cpp new file mode 100644 index 0000000..78d6756 --- /dev/null +++ b/userland/cpp/decltype.cpp @@ -0,0 +1,69 @@ +// https://cirosantilli.com/linux-kernel-module-cheat#cpp-decltype + +#include +#include +#include // declval + +int f() { + return 1; +} + +class C { + public: + int f() { return 2; } +}; + +int i; +decltype(i) g() { + return 1; +} + +int main() { +#if __cplusplus >= 201103L + // Implies reference while auto does not. + { + int i = 0; + int& ir = i; + decltype(ir) ir2 = ir; + ir2 = 1; + assert(i == 1); + } + + // Can be used basically anywhere. + { + int i = 0; + std::vector v; + v.push_back(0); + } + + // Return value. + { + decltype(f()) i; + assert(typeid(i) == typeid(int)); + + C c; + decltype(c.f()) j; + assert(typeid(j) == typeid(int)); + + // Return value without instance. Use declval. + // http://stackoverflow.com/questions/9760358/decltype-requires-instantiated-object + decltype(std::declval().f()) k; + assert(typeid(k) == typeid(int)); + } + + // decltype must take expressions as input, not a type. + // For types with the default constructor like `int`, we can just call the default constructor as in int(): + // https://stackoverflow.com/questions/39279074/what-does-the-void-in-decltypevoid-mean-exactly + // or we can just use declval. + { + decltype(int()) i = 0; + assert(typeid(i) == typeid(int)); + + decltype(std::declval()) j = 0; + assert(typeid(j) == typeid(int)); + } + + // Can be used to declare the return value of functions. + assert(g() == 1); +#endif +}