views:

106

answers:

2

I was just wondering if there was anything in the C++0x std lib already available to count the number of parameters in a parameter pack? I'd like to get rid of the field_count in the code below. I know I can build my own counter, but it just seems like this would be an obvious thing to include in the C++0x std lib, and I wanted to be sure it wasn't already there :) Home-grown counter implementations are most welcome too.

template<const int field_count, typename... Args> struct Entity {
    const tuple<Args...> data;
    const array<const char*, field_count> source_names;

    Entity() : data() {
    }
};
+1  A: 

Here's a link that may help you. Sample source from link:

template<typename... Args> struct count;

template<>
struct count<> {
    static const int value = 0;
};

template<typename T, typename... Args>
struct count<T, Args...> {
    static const int value = 1 + count<Args...>::value;
};
dirkgently
+6  A: 

Yes, you can use sizeof.... From the C++0x FCD (§5.3.3/5):

The identifier in a sizeof... expression shall name a parameter pack. The sizeof... operator yields the number of arguments provided for the parameter pack identifier. The parameter pack is expanded (14.5.3) by the sizeof... operator. [Example:

template<class... Types>
struct count {
    static const std::size_t value = sizeof...(Types);
};

end example ]

James McNellis
I like being able use sizeof this way, but now I'm curious/cautious. Typically I expect sizeof to return number of bytes, but here it unpacks and counts the args for me. With an array, the typical sizeof is going to give me the size in bytes of the array. Are there any "gotchas" people need to watch out for using sizeof...?I'm not expert enough w/ c++ to see at this point, but there's just something a little off to me about using sizeof to count things instead of getting their actual size in bytes. Am I just being semantically paranoid? lol.
pheadbaq
@pheadbaq: You can only use `sizeof...` on a parameter pack and it always returns the number of arguments in the pack. I don't think there is much room for error in its use, but I see what you mean. Personally, I think `sizeof...` is a ridiculous abuse of the `sizeof` keyword, but, I don't write the language, I just use it. :-)
James McNellis
Note the difference of `sizeof...(Types)` and `sizeof(Types)...`. The latter is counting bytes, the former is counting types :)
Johannes Schaub - litb
@Johannes: In `sizeof(Types)...`, the parameter pack is expanded and `sizeof` is applied to each of the types in the parameter pack, right? How are the results of the multiple `sizeof` expressions combined? Are the sizes summed? 14.5.3/6 just says "the syntactically-appropriate separator for the list" is used.
James McNellis
@James of course it depends where it's unpacked. `f(sizeof(Types)...)` would unpack it into an `initializer-list` (assuming `f` is a function taking integers), and that syntactically-appropriate separator would be a `,` (comma). It doesn't produce a single integer :) In this case `sizeof(Types)` is a pattern, just like `f(Types()...)` would be the unpacking of a pattern resulting in a number of value constructed objects being passed.
Johannes Schaub - litb
@Johannes: Okay, that's kind of what I thought. I was just confused by your comment "the latter is counting bytes." I'm glad Visual C++ only has support for a few C++0x features. I'd hate to have to learn them all at once.
James McNellis
@James i was doing a littl pun -.- I'm sorry for teh confusion
Johannes Schaub - litb
@Johannes: No problem :-P I'm easily confused on Fridays.
James McNellis