如何在不通过 using 声明公开字符串的情况下显式调用 std::string 析构函数?

Ita*_*iwa 1 c++ destructor stdstring

我有这个简单的例子:

#include <iostream>
#include <string>

int main(){

   std::string str = "Hi there!";
   std::cout << str << '\n';


   //using std::string;
   str.~string(); // error

}
Run Code Online (Sandbox Code Playgroud)

输出:

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();
Run Code Online (Sandbox Code Playgroud)
  • 如果我取消注释 main 中包含 using 声明的行,程序可以正常工作,但否则无法编译。

  • 我收到了那个错误,所以我怎么能在std::string不通过 ausing declaration或 a暴露它的情况下调用析构函数using directive?谢谢!

Atn*_*nNn 7

你永远不应该调用局部变量的析构函数。析构函数将在作用域结束时被调用。您可以引入自己的范围以使其尽早发生:

int main(){
   { 
       std::string str = "Hi there!";
       std::cout << str << '\n';
   } // str is destroyed
   std::cout << "no more str\n";
}
Run Code Online (Sandbox Code Playgroud)

如果您以特殊方式分配对象并且确实需要调用析构函数,请考虑使用destroy_at

std::string* ptr = new(...) std::string("Hi there!");
std::destroy_at(ptr);
Run Code Online (Sandbox Code Playgroud)

  • @AtnNn,在你的 `placement-new` 示例中,考虑使用 `std::aligned_storage` 而不是手动的 `unsigned char[]` 作为缓冲区,例如:`aligned_storage_t&lt;sizeof(std::string), alignas(std) ::string)&gt; mem;`。并且 `ptr` 应该从 `new()` 的返回值初始化,而不是从 `reinterpret_cast`'ing 缓冲区(除非你在 C++17 中使用 `std::launder`),例如:`auto* ptr = new (&amp;mem) std::string{"你好!"};` (3认同)
  • @ItachiUchiwa 为什么不使用 `std::variant` 而不是联合?为除“placement-new”以外的任何东西显式调用析构函数是一种巨大的代码味道。 (2认同)