I understand why do we need decltype(auto)
and it's difference from auto
, but I can't get why and when I should/need to use decltype(expression)
. In all examples on cppreference I can just use decltype(auto), I checked it.
Thanks in advance for your help.
The simplest example I could come up with is this:
void foo(int i) {
for (decltype(i) j = 0; j < i; ++j)
...
}
Here, the index j
automatically has the same type as the upper bound i
.
An alternative example is provided by a lambda expression:
[](auto i) {
for (decltype(i) j = 0; j < i; ++j)
...
}
but I can't get why and when I should/need to use
decltype(expression)
In C++11 you can use trailing return types but not auto-deduced return types. E.g.:
template<typename T, typename U>
auto add(T t, U u) -> decltype(t + u) { return t + u; }
C++14 equivalent is:
template<typename T, typename U>
decltype(auto) add(T t, U u) { return t + u; }
Another use is SFINAE, e.g. detecting existence of a member function with a specific name:
#include <iostream>
template<class T>
auto test_has_f(T* p) -> decltype(static_cast<void>(p->f()), std::true_type{}); // Cast to void to avoid user-defined operator,(), if any.
std::false_type test_has_f(void*);
template<class T>
using HasF = decltype(test_has_f(static_cast<T*>(0)));
struct A {};
struct B { void f(); };
int main() {
std::cout << HasF<A>::value << '\n'; // Outputs 0.
std::cout << HasF<B>::value << '\n'; // Outputs 1.
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With