gpt4 book ai didi

c++ - 这个 C++ 引用示例有问题吗?

转载 作者:行者123 更新时间:2023-12-01 23:19:17 25 4
gpt4 key购买 nike

我正在检查 aligned_storagecppref ,但我认为它的例子有问题。这是代码:

#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{};

// construct value in memory of aligned storage
// using inplace operator new
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
{
// note: needs std::launder as of C++17
return *reinterpret_cast<const T*>(&data[pos]);
}

// Delete objects from aligned storage
~static_vector()
{
for(std::size_t pos = 0; pos < m_size; ++pos) {
// note: needs std::launder as of C++17
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';
}

这里我们要创建一个使用 placement new 的静态 vector .问题是 typename std::aligned_storage<sizeof(T), alignof(T)>::type类型是 POD,不是 T .所以我们需要在使用前对其进行转换。我认为代码应该是这样的:

#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];
T* data_ptr = reinterpret_cast<T*>(data);

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{};

// construct value in memory of aligned storage
// using inplace operator new
new(&data_ptr[m_size]) T(std::forward<Args>(args)...);
++m_size;
}

// Access an object in aligned storage
const T& operator[](std::size_t pos) const
{
// note: needs std::launder as of C++17
return *reinterpret_cast<const T*>(&data_ptr[pos]);
}

// Delete objects from aligned storage
~static_vector()
{
for(std::size_t pos = 0; pos < m_size; ++pos) {
// note: needs std::launder as of C++17
reinterpret_cast<T*>(&data_ptr[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';
}

我说的对吗?虽然我不知道为什么原始代码在 clang 中工作。

更新:

让我更具体一点。按标准,aligned_storage类型是 POD 不是 T .所以它的实现可以如下:

template<std::size_t Len, std::size_t Align /* default alignment not implemented */>
struct aligned_storage {
struct type {
alignas(Align) unsigned char data[Len];
};
};

现在,如果您使用 data[pos] 访问它,地址会在unsigned char的基础上增加大小=1,不是sizeof(T)不是吗?

最佳答案

typename std::aligned_storage<sizeof(T), alignof(T)>::type data[N];

你似乎认为 &data[i]将返回此数组中第 i 个字节的地址,而实际上它将返回 i * sizeof(std::aligned_storage<sizeof(T), alignof(T)>) 的地址。第一个字节,与i * sizeof(T)相同第字节。 Example.

OP: The problem is that in aligned_storage data is allocated in for example unsigned char not type T. so when you are using &a[i] it access members assuming each member size is 1 (pointer was unsigned char) not sizeof(T).

这不是它的工作原理。什么类型并不重要 aligned_storage在引擎盖下使用,unsigned char[N]或其他东西。

为简洁起见,我们使用 using A = std::aligned_storage<sizeof(T), alignof(T)>::type; .

数组data类型为 A[N] .当您应用运算符时 []对它来说,它会衰减为 A * 类型的指针.

data[i]相当于*(data + i) .将整数与指针相加时,整数乘以sizeof尖的类型。尖型是A , 所以 sizeof(A)使用(等于 sizeof(T) )。

关于c++ - 这个 C++ 引用示例有问题吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68311667/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com