3

I wonder about the advantages of the new operator sizeof... (not to be confused with the sizeof operator). I searched the web and found a few examples that seem all like the following one:

template<class... ArgTypes>
std::size_t GetLength()
{
    return sizeof...(ArgTypes);
}

I think the examples are not illustrative.

Are there any real examples to illustrate that sizeof... is very useful?

Updates:

I found another examples from here that seem more meaningful:

template<class ...A> void func(A ...args){
   typedef typename common_type<A...>::type common;
   std::array<common, sizeof...(A)> a = {{ args... }};
}

template<typename... A> int func(const A&... args)
{
  boost::any arr[sizeof...(A)] = { args... };
  return 0;
}
Community
  • 1
  • 1
xmllmx
  • 39,765
  • 26
  • 162
  • 323
  • I use it all the time... – Kerrek SB Feb 19 '13 at 15:01
  • @KerrekSB how? I didn't know such a thing even existed. – Luchian Grigore Feb 19 '13 at 15:01
  • @Kerrek, could you give me some convincing examples? Thanks in advance. – xmllmx Feb 19 '13 at 15:02
  • 2
    `sizeof...(T)` provides actual functionality. Sure it can be implemented with the rest of the language, and look like `size_of()` but having it built-in does not hurt (it gives opportunity for better performance and adds no new keywords) – R. Martinho Fernandes Feb 19 '13 at 15:02
  • It's of such a common use that they actually provided a keyword for doing something that is easily done with trivial template metaprogramming. [Here](http://stackoverflow.com/questions/14261183/how-to-make-generic-computations-over-heterogeneous-argument-packs-of-a-variadic) is a use case, but you could find zillions. – Andy Prowl Feb 19 '13 at 15:03
  • 1
    I am confused as to what your "more" is referring to. more elegant than what? more expressive than what? The only other way to count the number of elements in a parameter pack I know is a recursive metafunction... – PlasmaHH Feb 19 '13 at 15:03
  • More concise, more elegent, and more expressive than what? As far as I know, it's the only sensible way to get the number of arguments in a variadic pack. Or are you asking why you might want to know the size at all? – Mike Seymour Feb 19 '13 at 15:03
  • @AndyProwl "trivial template metaprogramming" lol – Luchian Grigore Feb 19 '13 at 15:03
  • @LuchianGrigore: `sizeof...`? You kidding me :D – Andy Prowl Feb 19 '13 at 15:03
  • 1
    @LuchianGrigore: Just look at any kind of variadic index-expanding code. Anything that takes a pack and does like a for-each or `get...` thing.... – Kerrek SB Feb 19 '13 at 15:04
  • Not everyone uses variadic templates... – Luchian Grigore Feb 19 '13 at 15:06
  • @PlasmaHH, for example, there are two methods to do the same thing, A is with 'sizeof...', B is without 'sizeof...'. If B is obviously more complicated and tedious than A, then we can say A is more concise, more elegant, and more expressive than B. – xmllmx Feb 19 '13 at 15:09
  • @xmllmx: Well, the question is what are those A and B for you. I would say sizeof... and a template metafunction. And for me the metafunction is obviously much more work. So since this is obviously not obvious for you, I am wondering what your B is... – PlasmaHH Feb 19 '13 at 15:10
  • The question needs clarification IMO. What would you expect to be offered *instead* of `sizeof...`? – Nikos C. Feb 19 '13 at 15:11
  • 1
    @NikosC. `template struct sizeer{enum{value=0};}; template struct sizer{enum{value=1+sizer::value};};`, with similar ones for various types, is what I'd expect to use instead of `sizeof...` if it didn't exist. Note that it requires an O(N) recursion depth to find the size of a list of N parameters, while `sizeof...` does it in O(1) depth. As for a use of `sizeof...`, whenever you want to build an indexing to shove variardic parameters into a tuple or extract same you end up using it. – Yakk - Adam Nevraumont Feb 19 '13 at 16:38
  • Major reasons 1) it is readable. 2) it is more efficient than alternatives (compiling speed). Example ... you want to raise compile time noise when sizeof...(X) > 42. What you do? – Öö Tiib Feb 20 '13 at 01:55
  • 1
    Here is [an example](http://stackoverflow.com/a/15014171/596781)... – Kerrek SB Feb 21 '13 at 23:58

3 Answers3

4

Here is my example of what you can do with sizeof...:

/// Transform a single boolean value into a number
constexpr unsigned int boolCode(bool value) {
    return value;
}

/// Transform a sequence of booleans into a number
template <typename... Args>
constexpr unsigned int boolCode(bool value, Args... others) {
    return value << sizeof...(others) | boolCode(others...);
}

And this handy function could be used in a switch statement, like this:

switch (boolCode(condition1, condition2, condition3)) {
case boolCode(false,false,false): //...
case boolCode(false,false,true): //...
case boolCode(false,true,false): //...
case boolCode(false,true,true): //...
case boolCode(true,false,false): //...
case boolCode(true,false,true): //...
case boolCode(true,true,false): //...
case boolCode(true,true,true): //...
}
Gart
  • 2,297
  • 1
  • 28
  • 36
2

you probably want to read discussion between STL and CornedBee in the comments: http://channel9.msdn.com/Series/C9-Lectures-Stephan-T-Lavavej-Core-C-/Stephan-T-Lavavej-Core-Cpp-8-of-n#comments

Important bit:

sizeof... is not just syntactic sugar, though. A manually implemented sizeof... would have linear "runtime" (number of instantiations), whereas the built-in sizeof... is O(1). (One big issue of variadics as they are is that compilation tends to be very slow, due to lack of random access into arguments packs. Some guy (I think from Boost) studied this and found that compilation speed of Boost.Tuple (a preprorcessor-powered non-variadic tuple) compiled significantly faster than a naive variadics-based version.)

NoSenseEtAl
  • 28,205
  • 28
  • 128
  • 277
-3

The first and foremost reason sizeof was introduced into C++ was because it was present in C, where it is necessary in order to know how much memory to allocate, e.g. malloc( n * sizeof(struct MyClass) ). In C++, it's used in similar cases, where allocation and initialization are separate, for example in container classes, or variants, or maybe classes.

It's also been known to be used in template meta-programming, in conjunction with function override resolution. Things along the lines of: sizeof( discriminatorFunction( someArgs ) ) == sizeof( TrueType ).

James Kanze
  • 150,581
  • 18
  • 184
  • 329
  • 7
    The question refers to `sizeof...`, not `sizeof`. These are different things (http://en.cppreference.com/w/cpp/language/sizeof...) And the question right now is unclear anyway, since the OP doesn't state what he would expect as an alternative to `sizeof...`. – Nikos C. Feb 19 '13 at 15:13
  • OP meant `sizeof...` not `sizeof`. – David G Feb 19 '13 at 23:46