6

while playing and trying to calculate total size of vector I tried something like

vector<double> vd;
auto area = vd.size()* sizeof (vd::value_type); 
//Ive seen Stepanov use area as name for this kind of size, idk if he adds the sizeof vd also to area :)

Unfortunately this doesnt work... I need to use vector<double>::value_type but that makes code less readable. Can it be made to work? I dont like sizeof vd.front() because it just looks ugly to write front() for this.
EDIT: decltype variants also fit in what I would call ugly category...

NoSenseEtAl
  • 28,205
  • 28
  • 128
  • 277
  • 1
    Argument to sizeof is not evaluated in the way you suggest - think of it in this way: compiler looks at what `vd.front` returns and applies sizeof at that type, there is no function call happening in here. – Fiktik Dec 18 '12 at 15:51
  • read what i said... i know size of is compile time... just .front() is ugly because it doesnt signal the intent... it could be .back() [.size()-1]... – NoSenseEtAl Dec 18 '12 at 16:19
  • my apologies for bad wording... replaced "call" with "write" it is easy to write one thing while thinking something else... :/ – NoSenseEtAl Dec 18 '12 at 16:28

3 Answers3

9

I think decltype can be used:

auto area = vd.size() * sizeof(decltype(vd)::value_type);

as you are using auto I assume C++11 is permitted.

Confirmed with g++ v4.7.2 and clang v3.3.

hmjd
  • 120,187
  • 20
  • 207
  • 252
  • Works perfectly. Note to eclipse CDT users: the code is underlined (warning). It's a reported false-positive. (compile OK though) – johan d Mar 03 '14 at 09:53
4

How about a simple helper function?

template <typename Container>
size_t value_size(const Container &)
{
    return sizeof(typename Container::value_type);
}

[...]

vector<double> vd;
auto area = vd.size() * value_size(vd);

You could even overload the function so that it works with other containers such as arrays (of course, you would need to wrap size as well).

Ideally, the entire computation could be wrapped into a generic function:

template <typename Container>
size_t area(const Container &c)
{
    return c.size() * sizeof(typename Container::value_type);
}

//possible overload for arrays (not sure it's the best implementation)
template <typename T, size_t N>
size_t area(const T (&arr)[N])
{
    return sizeof(arr);
}

[...]

std::vector<double> vd;
auto vd_area = area(vd);
double arr[] = { 1., 2. };
auto arr_area = area(arr);
Luc Touraille
  • 79,925
  • 15
  • 92
  • 137
1

In C++11, you could use decltype(vd[0]):

auto area = vd.size()* sizeof (decltype(vd[0])); 

But in the particular scenario, you could just write this:

auto area = vd.size()* sizeof (vd[0]); 

Since the expression inside sizeof (and decltype too) will not be evaluated, both will work even if vd is empty.

Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • @Fiktik: I was writing that too. – Nawaz Dec 18 '12 at 15:55
  • 1
    This is pretty much the same as `sizeof vd.front()` mentioned in the question. – interjay Dec 18 '12 at 15:56
  • @interjay: I think what the OP wants syntactically different thing. And I think `sizeof (vd[0])` is syntactically different from `sizeof (vd.front())`, though I don't know why he would find either of them *ugly*. – Nawaz Dec 18 '12 at 16:00
  • @interjay read my comment to original question for ugly reasoning :) – NoSenseEtAl Dec 18 '12 at 16:20