我使用std::aligned_storage
并需要在aligned_storage
中存储数组类型。以下代码在visual cpp中编译,但不在Clang中编译。
template <typename T>
struct Foo
{
typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type store;
template <typename... Args>
Foo(Args&&... args)
{
new (&store) T { std::forward<Args>(args)... };
}
void Release()
{
reinterpret_cast<T*>(&store)->~T(); // Clang problems here
}
};
Foo<int> a(2); // ok
Foo<int[3]> b(1, 2, 3); // error in clang
具体错误是:
expression of non-scalar type 'T' (aka 'int [3]') cannot be used in a pseudo-destructor expression
这是有效的C ++吗?我应该如何正确地手动破坏数组类型?
答案 0 :(得分:3)
程序格式错误,您不能在数组类型上使用伪析构函数调用。 §5.2.4伪析构函数调用[expr.pseudo]:
- 在点
.
或箭头->
运算符后使用伪析构函数名称表示由类型表示的非类型类型的析构函数-name 或 decltype-specifier 。 ...- 点运算符的左侧应为标量类型。箭头操作符的左侧应是指向标量类型的指针。 ...
醇>
重载函数可以通过手动销毁每个数组元素(Live code)来适当地处理数组和非数组类型的破坏:
template <typename T>
void destroy(T& t)
{
t.~T();
}
template <typename T, std::size_t N>
void destroy(T (&t)[N])
{
for (auto i = N; i-- > 0;) {
destroy(t[i]);
}
}
template <typename T>
struct Foo
{
typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type store;
template <typename... Args>
Foo(Args&&... args)
{
new (&store) T { std::forward<Args>(args)... };
}
void Release()
{
destroy(reinterpret_cast<T&>(store));
}
};