避免 `delete[]` 接受隐式指针转换?

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

我有一个 class,带有指向指针的隐式转换运算符。取消分配该指针无效。与 delete[] 运算符一起使用时,我可以防止转换为指针吗?我想要一个编译时错误。对于 free 函数,我可以删除一个以 class 作为参数的重载。

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;
}

我认为需要一些聪明的东西才能达到预期的效果。


隐式转换的一个用例:说 A 实现一个作用域数组。转换使得 A 几乎可以替代 alloc/dealloc 对。需要显式转换的模板和迭代器。否则类c函数的调用点保持不变。

作为解决方法,您可以通过使转换不明确来防止在与 delete[] 运算符一起使用时转换为指针。

但是,根据其余代码的情况,这可能会导致所需用例出现不希望的歧义。

struct A {
  operator double*() const { return nullptr; }
  operator void*() const { return nullptr; }
};

每当涉及到在编译时停止某些东西时,您都会想到使用模板。

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;
}