vector<int> numbers; void f(vector<int> args);
Due to C++'s copying, args[0] has a different address than numbers[0], because a deep copy of the vector was made. As the article states, this is not what pass-by-value is referring to, otherwise it would be false that Java / Python / Ruby et al are pass-by-value. So I disagree that the terms are clear, but rather that there is confusion around these terms. As for wanting immutability, it's almost always better for C++ code to write functions not like f but instead like this:
void g(const vector<int>& args);
And apologies for the editorializing, but I do consider this a language design flaw, one inherited from the backwards compatibility for C, which already allowed struct's to be passed (non-pointer) as args and then copied to keep the caller untouchable. It makes C++ code more verbose and more error prone, and is quite difficult for new programmers to grasp.