避免 `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;
}
我有一个 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;
}