We can extract the entire contents of the WaitingForFirstRollWithXBonuses classes into a single method template:

  template<typename T0, typename T1, typename T2> State update(int pins, int& score, int& frame, int bonusMultiplier) const
  {
    score += pins*bonusMultiplier;
    if (IsStrike(pins)) {
      ++frame;
      if (frame == 10)
        return T0{};
      return T1{};
    }
    return T2{pins};
  }

And each of those WaitingForFirstRollWithXBonuses classes’ Update methods collapses to a single line.

Click next to see the final code and tests in their entirety.