如何在不通过 using 声明公开字符串的情况下显式调用 std::string 析构函数?
我有这个简单的例子:
#include <iostream>
#include <string>
int main(){
std::string str = "Hi there!";
std::cout << str << '\n';
//using std::string;
str.~string(); // error
}
输出:
g++ main.cxx -std=c++2a -o prog
main.cxx: In function ‘int main()’:
main.cxx:10:15: error: expected class-name before ‘(’ token 10 | str.~string();
回答
你永远不应该调用局部变量的析构函数。析构函数将在作用域结束时被调用。您可以引入自己的范围以使其尽早发生:
int main(){
{
std::string str = "Hi there!";
std::cout << str << '\n';
} // str is destroyed
std::cout << "no more str\n";
}
如果您以特殊方式分配对象并且确实需要调用析构函数,请考虑使用destroy_at:
std::string* ptr = new(...) std::string("Hi there!");
std::destroy_at(ptr);
- @AtnNn,在你的 `placement-new` 示例中,考虑使用 `std::aligned_storage` 而不是手动的 `unsigned char[]` 作为缓冲区,例如:`aligned_storage_t<sizeof(std::string), alignas(std) ::string)> mem;`。并且 `ptr` 应该从 `new()` 的返回值初始化,而不是从 `reinterpret_cast`'ing 缓冲区(除非你在 C++17 中使用 `std::launder`),例如:`auto* ptr = new (&mem) std::string{"你好!"};`
- @ItachiUchiwa 为什么不使用 `std::variant` 而不是联合?为除“placement-new”以外的任何东西显式调用析构函数是一种巨大的代码味道。
THE END
二维码