Avoid `delete[]` accepting an implicit pointer conversion?

114 Views Asked by At

I have a class with an implicit conversion operator to a pointer. Deallocating that pointer is not valid. Can I prevent the conversion to a pointer when used with the delete[] operator? I would like a compile time error. For the free function, I can delete an overload that takes the class as an argument.

void foobar(double*){}

struct A {
  // Please pretend I have a good reason for doing this.
  operator double*() const { return nullptr; }
};

void free(A&) = delete;

int main(){
  A a;
  
  // Just works TM
  foobar(a);

  // This compiles :(
  delete[] a;
  // This does not :)
  //free(a);
  return 0;
}

I think something clever would be needed for the desired effect.


A use case for implicit conversion: Say A implements a scoped array. Conversion makes A almost a drop in replacement for an alloc/dealloc pair. Templates and iterators requiring explicit conversion. Otherwise the call sites of c-like functions remain unchanged.

2

There are 2 best solutions below

0
Eljay On BEST ANSWER

As a workaround, you can prevent the conversion to a pointer when used with the delete[] operator by making the conversion ambiguous.

However, depending on the situation of the rest of the code, this may cause undesirable ambiguity for the desired use cases.

struct A {
  operator double*() const { return nullptr; }
  operator void*() const { return nullptr; }
};
3
Ravi Prakash On

Whenever it comes to stopping something at compile time you can think of using templates.

void foobar(double*){}

class A {
  // Please pretend I have a good reason for doing this.
  public : 
  operator double*() const { return nullptr; }
  template<typename type>
  void operator delete[] (void*, type size); 
};

template<typename type>
void free(void*);

template<>
void free<A>(void*) = delete;

int main(){
  A a;
  
  // Just works TM
  foobar(a);

  // Now this will not compile to ! :(
  delete[] a;
  // This does not :)
  //free(a);
  return 0;
}