9

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?

2 Answers 2

6

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;
    }
}
Sign up to request clarification or add additional context in comments.

Comments

2

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;
  }
};

2 Comments

Now it looks right. Can simplify a bit. You just no longer need to check that index < t.size(). Also, return X ? Y : false is the same as return X && Y.
I just like ternary operator. :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.