Provided the objects themselves are implemented correctly.
Of course, there are other things that are part of exception safety. Most importantly, you can never allow your function to be aborted by an exception while any objects are in an inconsistent state. E.g. this copy assignment operator of a string-like class is unsafe:
Code:
mystring & mystring::operator =(const mystring &rhs)
{
delete[] m_data;
m_data = new char[rhs.size() + 1];
std::memcpy(m_data, rhs.m_data, rhs.size() + 1);
return *this;
}
The reason: if the allocation fails, m_data is pointing at invalid memory. The object is in an invalid state.
(The operator is also unsafe regarding self-assignment, but that's a different issue.)