In general once you've signaled something has changed (via a condition variable) you need some code to run to handle that change and that code has to safely read the changed data. If you didn't have a lock associated with the cv then your thread waiting on the cv might wake up then try to (and fail) to acquire the lock associated with the data and therefore have to yield again. With a CV/Lock combo the underlying system can wake your thread up only if the thread can acquire the relevant lock as a unit and so be more efficient.
Its unlikely a CV on its own is useful as it gives no data above the fact it was signaled. If you imagine uses of cv - such as a thread-safe linked list with producers and consumers, you have variables representing {list, cv, lock}
. In this case you take the lock, mutate the list, release the lock then signal the cv. On you consumer thread you'll very likely need to take the lock once signaled to act on the list, so having the lock acquired once you wake up from the CV being signaled is a good thing.
Look at something like events on windows (::CreateEvent) which are cv's without the implicit lock, a lot of the time they'll have a lock associated with them, but just not built into the actual usage.
Although this isn't the original reason condition variable in pthreads was created (they used the lock to protect the cv itself which is no longer needed in c++) the reason and usefulness of locks with cv's has migrated to whats in this answer.