Example
constexpr auto foo() {
auto p = new int{42};
delete p;
return true;
}
constexpr auto bar() {
auto p = new int{42};
//delete p;
return false;
}
static_assert(foo());
static_assert(bar()); // compilation error - allocation performed here was not deallocated
Puzzle
- Can you implement a simplified version of
unique_ptr
which will take advantage ofconstexpr new
?
/*TODO - constexpr unique_ptr */
template<class T>
constexpr auto foo(T value) {
return unique_ptr{new T(value)};
}
static_assert(std::is_same_v<unique_ptr<int>, decltype(foo(int{}))>);
static_assert(std::is_same_v<unique_ptr<double>, decltype(foo(double{}))>);
static_assert(0 == *foo(0));
static_assert(42 == *foo(42));
static_assert(4.2f == *foo(4.2f));
static_assert(42.d == *foo(42.d));
Solutions
template<class T>
class unique_ptr {
public:
constexpr unique_ptr(T* ptr) : ptr(ptr) {}
constexpr T operator*() { return *ptr; }
constexpr ~unique_ptr() { delete ptr; }
private:
T* ptr = nullptr;
};
template <typename T>
struct unique_ptr {
constexpr unique_ptr(T* p) : ptr_(p) {}
constexpr ~unique_ptr() { delete ptr_; }
constexpr const auto& operator*() const { return *ptr_; }
private:
T* ptr_;
};
template<typename T>
class unique_ptr
{
public:
constexpr unique_ptr(T* value) : _value(value) {}
constexpr T& operator*() {return *_value;}
constexpr ~unique_ptr() {delete _value;}
private:
T* _value;
};
template <typename T>
class unique_ptr {
T* ptr;
public:
constexpr unique_ptr(T* ptr) : ptr(ptr) {}
constexpr std::add_lvalue_reference_t<T> operator*() { return *ptr; }
constexpr ~unique_ptr() { delete ptr; }
};
template <typename T>
struct unique_ptr {
constexpr explicit(true) unique_ptr(T *arg) : val(arg) {}
constexpr ~unique_ptr() { delete val; }
[[nodiscard]] constexpr T operator*() const noexcept { return *val; }
T *val;
};