好吧,我的同事非常深入地讨论了为析构函数消除不必要的代码实例化的问题。还有同样的情况,如this question中所述:
.text
部分的空间非常有限(少于256 KB)我们有一个目标,通过可用的.text
部分空间非常有限
不幸的是,GCC编译器显然会为非虚拟析构函数实例化代码,实际上没有副作用。
为了摆脱这些实例,他想出了以下包装器构造,以消除无用的析构函数调用:
包装类:
#include <iostream>
#include <cstdint>
#include <utility>
template <typename T>
struct noop_destructor {
public:
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
template<typename... Args>
noop_destructor(Args&&... args) {
new (reinterpret_cast<void*>(wrapped_data)) T(std::forward<Args>(args)...);
}
explicit noop_destructor(const noop_destructor& rhs) {
std::copy(rhs.wrapped_data,rhs.wrapped_data+sizeof(T),wrapped_data);
}
noop_destructor& operator=(const noop_destructor& rhs) {
std::copy(rhs.wrapped_data,rhs.wrapped_data+sizeof(T),wrapped_data);
return *this;
}
pointer operator->() {
return reinterpret_cast<pointer>(wrapped_data);
}
const_pointer operator->() const {
return reinterpret_cast<const_pointer>(wrapped_data);
}
reference operator*() {
return *reinterpret_cast<pointer>(wrapped_data);
}
const_reference operator*() const {
return *reinterpret_cast<const_pointer>(wrapped_data);
}
private:
uint8_t wrapped_data[sizeof(T)] __attribute__ ((aligned (__BIGGEST_ALIGNMENT__)));
};
一个包装类(只是忽略在析构函数中调用std::cout << ...
的副作用,要包装的现实生活类,只有空,非虚拟< / em> destructors)
class A {
public:
A() : x_() {}
A(int x) : x_(x) {}
~A() {
std::cout << "noop destructor call of class A" << std::endl;
}
void foo() {
std::cout << "x_ = " << x_ << std::endl;
}
private:
int x_;
};
一些演示行为的实例:
int main() {
A a1(5);
noop_destructor<A> a2;
a1.foo();
(*a2).foo();
return 0;
}
这种方法运作正常(as you can see from the above code sample)。
我真的不喜欢它,你是否没有证明一个类实际上是否可以用noop_destructor<>
包裹,并且没有指示T
的析构函数实际上是空的,并且可以安全地消除或不安全。
有没有人有一个想法,如何从语义层面使这更安全?