【发布时间】:2018-05-23 22:57:39
【问题描述】:
以下示例来自cppreference.com的std::aligned_storage page:
#include <iostream>
#include <type_traits>
#include <string>
template<class T, std::size_t N>
class static_vector
{
// properly aligned uninitialized storage for N T's
typename std::aligned_storage<sizeof(T), alignof(T)>::type data[N];
std::size_t m_size = 0;
public:
// Create an object in aligned storage
template<typename ...Args> void emplace_back(Args&&... args)
{
if( m_size >= N ) // possible error handling
throw std::bad_alloc{};
new(data+m_size) T(std::forward<Args>(args)...);
++m_size;
}
// Access an object in aligned storage
const T& operator[](std::size_t pos) const
{
return *reinterpret_cast<const T*>(data+pos);
}
// Delete objects from aligned storage
~static_vector()
{
for(std::size_t pos = 0; pos < m_size; ++pos) {
reinterpret_cast<T*>(data+pos)->~T();
}
}
};
int main()
{
static_vector<std::string, 10> v1;
v1.emplace_back(5, '*');
v1.emplace_back(10, '*');
std::cout << v1[0] << '\n' << v1[1] << '\n';
}
在示例中,operator[] 只是 reinterpret_casts std::aligned_storage* 到 T* 没有 std:launder,并直接执行间接。然而,根据this question,这似乎是未定义的,即使T 类型的对象曾经被创建过。
所以我的问题是:示例程序真的违反了严格的别名规则吗?如果不是,那我的理解有什么问题?
【问题讨论】:
-
你的问题基本上可以归结为,“这个答案真的说明了什么吗?”是的,它确实说明了它所说的内容。
-
@NicolBolas,因为cppreference.com是一个著名的网站,所以当我的理解与它发生冲突时,我认为我的理解首先有问题。
标签: c++ language-lawyer reinterpret-cast strict-aliasing