【发布时间】:2021-11-30 02:44:10
【问题描述】:
我正在通过this particular SO 了解如何为自定义删除器指针节省内存空间。在答案的底部,它提供了 C++11 中的自定义编写版本。
在尝试理解代码数十分钟后,我发现 Big 3 中的一些编译器不一致,其中 clang 编译,而其他两个则抱怨编译器错误。 (Live Demo)
我的代码与其他 SO 答案略有不同。就是这样:
#include <cstdlib>
#include <iostream>
#include <memory>
#include <type_traits>
using namespace std;
template <class T, T t>
struct val {
constexpr operator typename decay<T>::type() const noexcept {
return t;
}
};
using default_free = val<decltype(free), free>;
int main(void) {
unique_ptr<void, default_free> p(malloc(42));
cout << p.get() << endl;
p.reset();
cout << p.get() << endl;
return 0;
}
如果我在这里错了,请纠正我。在我看来,诀窍是提供一个 constexpr 函数,该函数可以将 default_delete 类型的对象强制转换为具有 t 值的函数指针(free 作为其实例化)。
那么问题来了:哪个编译器是正确的?
【问题讨论】:
-
val<decltype(&free), &free>工作 Demo -
就像你在 C++17 中一样,
template <auto t> struct val;和val<&free>Demo。 -
看起来gcc trunk可以工作了,应该下个正式版会修复:godbolt.org/z/r445dY6hM
标签: c++ templates c++17 language-lawyer constexpr