I don't disagree, that in C++ that's the way it works.
As Christian points out, there is absolutely no difference between emitting dataChanged() with two arguments vs. with a third argument being an empty (but explicitly declared) QVector<int>(). Both versions should compile to exactly the same thing (with the compiler inserting the default argument in the first instance), so there is absolutely no way that a slot receiving the signal can tell how it was called in the source code. If you are seeing a difference in behavior if you build and run code written first one way and then the other with no other code changes and exactly the same runtime test conditions then I would also be at a loss to explain why.