Ничто из того, что вы упомянули, не является потокобезопасным, ни по стандарту, ни на практике.
Причина, по которой стандарты не предписывают безопасность нитей, заключается в том, что безопасность нитей сопряжена с определенными затратами. В общем, C ++ старается не давать вам того, о чем вы не просите. Если вам нужна безопасность нитей, вы должны создать ее самостоятельно. Это верно даже в C ++ 0x, который включает в себя различные примитивы синхронизации.
Причины, по которым эти вещи не являются поточно-ориентированными на практике, различны. Как правило, контейнеры STL не являются потокобезопасными, поскольку каждая из их основных операций обновления выполняется в несколько этапов. Если поток пытается прочитать или обновить контейнер, пока другой поток находится в процессе его обновления, контейнер будет находиться в неопределенном состоянии, и, следовательно, результаты будут непредсказуемыми.
В случае типов POD операции чтения и записи также могут выполняться в несколько этапов. Этот самый простой пример - 64-разрядное целое число на 32-разрядной машине. Чтобы прочитать или установить значение, нужно как минимум две инструкции. Еще раз, это означает, что если поток пытается прочитать или обновить значение, пока другой поток находится в процессе его обновления, результаты будут непредсказуемыми.