Reputation: 9292
I am using an external library which defines a struct with an unsigned int C-style array:
struct Foo
{
unsigned int bar[8];
}
In my code, I want to get the numeric_limits::max() for that type in order to check out of bounds values, and avoid passing overflowed values to the library.
So I do :
auto n = Foo().bar[0];
if(myBar > std::numeric_limits<decltype (n)>::max())
{
error("The Foo library doesn't support bars that large");
return false;
}
This works, but is there a more elegant c++11 way not implying declaring a variable? If I use decltype(Foo().bar[0])
I have an error, as this returns a reference type, which numeric_limits
doesn't like.
Upvotes: 1
Views: 288
Reputation: 313
You could have something like this :
#include <limits>
#include <type_traits>
struct Foo {
unsigned int bar[8];
};
int main() {
auto max_val = std::numeric_limits<std::remove_all_extents_t<decltype(std::declval<Foo>().bar)>>::max();
return 0;
}
std::remove_all_extents
removes the "array part" of your member. The advantage is that this will work on simple int
, int []
, and multi-dimensional arrays too. As you don't make use of the operator[]
, you avoid the "reference problem" as well.
std::declval
allows to determine the type of bar
if you don't have an instance at hand.
Upvotes: 0
Reputation: 172864
For lvalue expressions like Foo().bar[0]
, decltype
yields type T&
, i.e. lvalue-reference type.
You can remove the reference part by using std::remove_reference
.
std::numeric_limits<std::remove_reference<decltype(Foo().bar[0])>::type>
Upvotes: 2