typeof
is a gcc extension and is not part of the C++ standard.typeof
deprecated in C++11? in other words, is it allowed to still use it as a gcc extension when using C++11?typeof
with decltype
yields the same behaviour of the code? template<typename T> class wrapper
. What is the best way to declare wrapper_some_field
such that it is equivalent to: Wrapper<typeof(some_field)> wrapper_some_field
The typeof keyword is a new extension to the C language. The Oracle Developer Studio C compiler accepts constructs with typeof wherever a typedef name is accepted, including the following syntactic categories: Declarations. Parameter type lists and return types in a function declarator. Type definitions.
typeof is a extension featured in many implementations of the C standard to get the type of an expression. It works similarly to sizeof , which runs the expression in an “unevaluated context” to understand the final type, and thusly produce a size.
typeof is defined in the GCC extension for C and in the C++ Boost library.
Is the word
typeof
deprecated in C++11? in other words, is it allowed to still use it as a gcc extension when using C++11?
It's not deprecated. It never existed as a keyword. gcc suggests that if you compile with -std=c++**
that you instead use __typeof__
.
Is it correct to say that replacing every
typeof
withdecltype
yields the same behaviour of the code?
No. For example, given:
int& foo();
decltype(foo())
is int&
but __typeof__(foo())
is int
.
Assume I have
template<typename T> class wrapper
. [...]
You could write wrapper<std::remove_reference_t<decltype(some_field)>> wrap{some_field}
, but it'd be cleaner to write a construction function template:
template <class T> wrapper<T> make_wrapper(T const& val) { return {val}; }
auto wrap = make_wrapper(some_field);
Or, with forwarding:
template <class T>
wrapper<std::decay_t<T>> make_wrapper(T&& val) {
return {std::forward<T>(val)};
}
Although in C++17 you wouldn't do this at all and would just use class template argument deduction:
template <class T> struct wrapper { T t; };
template <class T> wrapper(T) -> wrapper<T>;
auto wrap = wrapper{42}; // wrap is a wrapper<int>
And in C++20, you won't even need the deduction guide.
#define typeof(...) std::remove_reference_t<decltype(__VA_ARGS__)>;
However, if you want to create storage for a type T
, the way to do it in C++11 is to use std::decay_t
, or in some situations write your own extension that stores C-style arrays into a std::array
.
Wrapper<std::decay_t<T>> wrapper_some_field;
if you want to pass Wrapper
a type suitable for storing inside of it.
decay
removes references, converts functions to pointers-to-functions, and arrays of T to pointers-to-T, and removes top-level const
and volatile
after that. These are operations similar to what happens when you pass things to a function as part of the "decay-to-pointer/value" operations.
The result is a type "suitable for storage". As noted, I'd prefer that a int[4]
decay to a std::array<int,4>
but you cannot have everything.
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