【问题标题】:How to invoke descructor of static array in C++ template?如何在 C++ 模板中调用静态数组的析构函数?
【发布时间】:2014-07-11 09:29:47
【问题描述】:

如何在 C++11 中实现以下模板函数以支持数组类型作为模板参数?当前编译失败,错误如下。有什么语法技巧可以解决这个问题吗?

template<typename T>
void destroy(T &o) { o.~T(); }

int main()
{
    int x;
    char y[3];
    destroy(x);
    destroy(y);
}

输出:

$ g++ test.cpp
test.cpp: In instantiation of ‘void destroy(T&) [with T = char [3]]’:
test.cpp:9:18:   required from here
test.cpp:2:26: error: request for member ‘~char [3]’ in ‘o’, which is of non-class type ‘char [3]’

更新: 如果像 struct Storage { CharType value; 这样的包装器缓冲区} 用于代替 CharType(即 Storage* 而不是 CharType*),那么这可以允许通过 Storage::~Storage() 调用 CharType = 数组的析构函数。这可以在导致这个问题的代码中起作用。但是,问题仍然存在:是否允许在 C++ 中显式调用固定大小数组的析构函数,如果允许,那么如何执行此操作?

【问题讨论】:

  • 为什么要手动调用析构函数? :(
  • 这只是我需要做的一个简约版本。在我的代码中,有一个动态分配的缓冲区(不使用 new T[]),所以我需要销毁手动分配的每个元素 T。我知道 POD 类型的析构函数是无操作的。但我需要 destroy(T &) 可编译为任何具有可见析构函数的类型,包括 POD 类型。
  • @dzidzitop:最小的例子不包括这个事实:请在你的问题中动态分配对象。
  • 好的。以下是无法编译的代码:github.com/dzidzitop/libafc/blob/master/src/afc/… (afc::FastStringBuffer::~FastStringBuffer())
  • 是的,可以使用类似的东西。然而,问题在于 C++ 语言本身,而不是如何用类替换内置数组。

标签: c++ templates c++11 g++ g++-4.7


【解决方案1】:

对数组稍微明确一点,不要忘记通过引用传递它们以避免数组衰减:

template<typename T>
void destroy(T &o) { o.~T(); }

template<typename T, size_t N>
void destroy(T (&o)[N]) {
    for(size_t i = N; i-- > 0;)
        destroy(o[i]);
}

顺便说一句:只有 type-names 支持调用 dtor。 int 不是类型名称。所以,这并不困难,因为谁会想要显式地破坏一个显式的基本类型呢?

【讨论】:

  • 快速,如果直接调用 o.~T()(其中 o 可以是一个数组)被替换为 destroy(o) 如上所述,那么这有助于销毁一个放置分配的数组数组(对象)以最小的努力。然而,数组似乎根本没有析构函数,并且就 C++ 语义而言是一种非常不寻常的类型。
  • @dzidzitop:是的,这就是我去destroy 的原因。正如您所说,C 和 C++ 中的原生数组类型充其量只是二等公民,其行为大部分来自数组衰减......
猜你喜欢
  • 1970-01-01
  • 2016-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-24
  • 2012-10-24
相关资源
最近更新 更多