template <class T>
struct Obj {
// Plain Old Data for T
using InternalPod = typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type;
InternalPod value_pod_;
template<class... Args>
Obj(Args&&... args) { // my constructor
// placement new: construct the value in the statically allocated space
new (&value_pod_) T(std::forward<Args>(args)...); // <- can this whole expression throw if the constructor of T doesn’t throw?
}
}
Normal new
can throw if the allocation fails or if the construction fails (correct me if there are other cases), but since placement new doesn’t allocate any space, can the new expression throw if the constructor of T
doesn’t throw?
I.e. is the following noexcept
specification correct and safe?
Obj(Args&&... args) noexcept(noexcept(T(std::forward<Args>(args)...))) {
new (&value_pod_) T(std::forward<Args>(args)...);
}