Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ variadic template iterate vector and compare elements

I have a variadic class template

template <size_t ...T>
struct Foo 
{
   std::vector<size_t> t;

   bool IsEqual()
   {
     //??
   }

};

which I want to use like:

Foo<1,2,3,4> foo;
foo.data = {1,2,3,4};
foo.IsEqual();

How can I implement IsEqual to iterate and compare every element of the vector and return false / true if the elements are in the same order as the template parameters?

like image 301
Martin Perry Avatar asked Sep 29 '15 15:09

Martin Perry


2 Answers

Use the index sequence trick:

bool IsEqual()
{
    return t.size() == sizeof...(T) &&
        IsEqual(std::make_index_sequence<sizeof...(T)>{});
}

with:

template <size_t... Is>
bool IsEqual(std::index_sequence<Is...> ) {
    bool valid = true;
    using expander = int[];
    expander{0,
        (valid = valid && t[Is] == T,
        0)...
    };

    return valid;
}    

Could even do this in one function by taking advantage of the fact that every value computation and side effect in an initializer-clause is sequenced before the next one by doing this in one go:

bool IsEqual()
{
    if (t.size() == sizeof...(T)) {
        auto it = t.begin();
        bool valid = true;

        using expander = int[];
        expander{0,
            (valid = valid && *it++ == T,
            0)...
        };

        return valid;
    }
    else {
        return false;
    }
}
like image 58
Barry Avatar answered Nov 20 '22 20:11

Barry


Simply unpack template arguments.

template <size_t ...T>
struct Foo
{
  std::vector<size_t> t;

  bool IsEqualTemplate(size_t index)
  {
    return true;
  }

  template <typename FIRSTARG, typename ...OTHERARGS>
  bool IsEqualTemplate(size_t index, FIRSTARG firstArg, OTHERARGS... otherArgs)
  {
    return t[index] == firstArg && IsEqualTemplate(index + 1, otherArgs...);
  }

  bool IsEqual()
  {
    return t.size() == sizeof...(T) ? IsEqualTemplate(0, T...) : false;
  }
};
like image 29
Michal Žák Avatar answered Nov 20 '22 19:11

Michal Žák