int main(void)
{
std::string foo("foo");
}
我的理解是上面的代码使用了默认的分配器来调用new。因此,即使 std::string foo 是在堆栈上分配的,foo 内部的内部缓冲区也会在堆上分配。
如何创建一个完全在堆栈上分配的字符串?
int main(void)
{
std::string foo("foo");
}
我的理解是上面的代码使用了默认的分配器来调用new。因此,即使 std::string foo 是在堆栈上分配的,foo 内部的内部缓冲区也会在堆上分配。
如何创建一个完全在堆栈上分配的字符串?
我最近想自己做这件事,发现以下代码很有启发性:
它定义了一个新的std::allocator,可以为 STL 容器的初始存储分配提供基于堆栈的分配。我最终找到了一种不同的方法来解决我的特定问题,所以我自己并没有真正使用代码,但也许它对你有用。请务必阅读代码中有关用法和警告的注释。
对于那些质疑这样做的实用性和合理性的人,请考虑:
一些人评论说,使用基于堆栈的分配的字符串不会std::string好像这会以某种方式降低其效用。诚然,您不能互换使用这两者,因此您将无法将您stackstring的函数传递给期望std::string. 但是(如果你做对了),你将能够使用stackstring你现在使用的所有相同的成员函数std::string,比如find_first_of(),append()等等 begin(),并且end()仍然可以正常工作,所以你将能够使用许多STL 算法。当然,它不会是std::string最严格的意义上的,但它仍然是实际意义上的“字符串”,它仍然非常有用。
问题是std::basic_string分配器有一个模板参数。但std::string不是模板,也没有参数。
因此,您原则上可以使用std::basic_string使用堆栈上内存的分配器的实例化,但它不会是std::string. 特别是,您不会获得运行时多态性,并且您无法将生成的对象传递给期望std::string.
你不能。除了...
std::string是一个实例化
std::basic_string<class CharType,
class Traits=char_traits<CharType>,
class Allocator=allocator<CharType> >
您可以想象定义一个使用alloca进行内存管理的 Allocator 类。这只有在分配器本身以及basic_string直接或间接调用它的方法都是inline. 使用此分配器创建的basic_string对象不会是a std::string,但它会(大部分)表现得像它。但是,对于有限的收益,这将是相当多的工作。具体来说,使用此类从函数返回值将是职业限制的举动。
我不知道您或其他任何人为什么要这样做。
我怀疑做这样的事情会很难做,不知道你为什么要这样做?要完全在堆栈上分配某些内容,编译器需要在编译时知道该事物的确切大小 - 在您的示例中,它不仅需要知道std::string元数据的大小,还需要知道字符串数据本身的大小. 这不太灵活,您可能需要不同的字符串类型,具体取决于您想要包含在其中的字符串数据的大小 - 并不是说不可能做到,只是它会使事情变得有点复杂。