Cron Merdek
Cron Merdek

Reputation: 1124

Variadic function to check equal lengths of STL containers

I am writing my first variadic function template. I am getting the error error: parameter packs not expanded with ‘...’:. Probably I cannot understand some easy concept here. I would like to store all passed in iterators in a vector. What is the right way to do this?

template<typename... Iterator>
bool IsEqualLength(Iterator&... its)
{
    std::vector<Iterator> vec_its {its...};
    int head = vec_its.front().size();

    bool is_diff_size = std::any_of(vec_its.begin(), vec_its.end(), 
        [&head](Iterator& cur){return cur.size() != head;});

    if(is_diff_size)
    {
        return false;
    } else {
        return true;
    }
}

This fails to compile with (under gcc 4.8.4 on Ubuntu):

../proc.h: In function ‘bool IsEqualLength(Iterator& ...)’:
../proc.h:32:24: error: parameter packs not expanded with ‘...’:
  std::vector<Iterator> vec_its {its...};
                        ^
../proc.h:32:24: note:         ‘Iterator’
../proc.h:35:87: error: parameter packs not expanded with ‘...’:

Upvotes: 2

Views: 83

Answers (1)

Barry
Barry

Reputation: 303127

You're using two different packs in this statement:

std::vector<Iterator> vec_its {its...};

its is expanded, but Iterator isn't a single type... it's a pack too, and you're failing to expand it. Hence the error (which specifically points out Iterator).

If all you want is the sizes of the containers, you could just call size() on all the passed-in containers (containers, not iterators!) and put that in an array (no need for dynamic allocation):

template <typename... Container>
bool isEqualLength(Container&&... cs) {
    size_t sizes[] = {cs.size()...};

    return std::all_of(std::begin(sizes), std::end(sizes),
        [&sizes](size_t cur){return cur == sizes[0]; });
}

Upvotes: 4

Related Questions