在C++17中引入了std::optional,我很高兴这个决定,直到我看到ref.我从Scala、Haskell和Java8知道Optional/Maybe,其中optional是一个monad并遵循monadic法则。C++17实现中不是这种情况。我应该如何使用std::optional,没有像map和flatMap/bind这样的函数,那是什么使用std::optional与例如返回-1或函数计算结果失败时的nullptr相比有优势吗?对我来说更重要的是,为什么std::optional没有设计成monad,有什么原因吗? 最佳答案
我正在尝试用C++初始化一个井字棋盘,但输出总是给我六进制值。有没有办法将它们转换为实际的字符串值?#include#includeusingnamespacestd;intmain(){stringtab[5][5]={"1","|","2","|","3","-","+","-","+","-","4","|","5","|","6","-","+","-","+","-","7","|","8","|","9"};for(inti=0;i 最佳答案 您正在将tab[i]的值发送到cout,因此您将获得内存地址。您可能希望将项目
在C++17中,std::shared_ptr有一个运算符[]以允许索引基于vector的指针(http://en.cppreference.com/w/cpp/memory/shared_ptr/operator_at)如果这样的运算符不可用,我如何获得类似的访问,我仍然想对元素数组使用智能指针,例如:std::shared_ptrdata;data.reset(newunsignedchar[10]>;//usedata[3]; 最佳答案 像这样:data.get()[3]但是,请记住Nathan在评论中所说的话。std::sh
在他的C++CoreGuidelines,BjarneStroustrup建议在按引用传递数组时使用span。为什么不只传递一个std::array对象? 最佳答案 按值传递std::array将是复制它们。gsl::span的要点是采用它们的函数引用现有的数据数组。gsl::span能够获取运行时定义大小的数组。std::array在编译时固定。gsl::span不关心什么类型拥有数组;它只是一个指针+大小。因此,基于span的接口(interface)可以从std::vector、QVector和许多其他类型中获取数据。基于st
C++17将包含std::byte,一种用于一个原子可寻址内存单元的类型,在典型计算机上具有8位。在此标准化之前,在指向“原始”内存时已经存在一些困境-在一方面使用char*/unsignedchar*还是使用void*在另一边。现在,首选void*的原因之一已被删除-std::byte与char没有相同的含义;这是关于原始内存,而不是字符。所以,我的问题是:对于std::byte的时代,关于什么时候更喜欢它而不是void*以及什么时候有什么好的经验法则是不是反过来了?当然,当您处理旧代码或C代码时,您会受到它所接受内容的限制;我主要指的是新代码,您可以在其中选择所有类型。
std::visit支持多种输入变体。但是,代码应该处理来自这些变体的类型的所有组合。有没有办法跳过不“有意义”的组合?例如:templatestructoverloaded:Ts...{usingTs::operator()...;};templateoverloaded(Ts...)->overloaded;intmain(){std::variantv1{'s'};std::variantv2{10};std::visit(overloaded{[](inta,intb){},[](inta,floatb){},[](inta,charb){},[](floata,intb){}
我有很多使用队列的情况,队列的大小可以增长到数百个。不幸的是,如果有必要,没有清空队列的一次性解决方案。我想知道是否使用作用域队列进行交换,然后让作用域队列被销毁,是否会破坏任何内存分配/管理规则?以下片段是我所提议的示例。似乎有效,如果长时间使用多次,则不确定结果。#include#include#includeintmain(){std::queuefoo;foo.push(10);foo.push(20);foo.push(30);std::coutbar;swap(foo,bar);}std::cout 最佳答案 您的代码没
插入新数据时,std::map是否移动已插入的值? 最佳答案 map被实现为一棵树,当你插入一个新元素时,树可能需要重新平衡。这不会使任何迭代器或对树中元素的引用无效。这种平衡是通过指针的操作来完成的,所以你没有什么可担心的;节点本身保持不变。平衡涉及通过重新分配指针告诉节点他们的child、parent和sibling是谁,从而改变树的结构,但这是一个实现细节。从逻辑上讲,一切都没有改变。 关于c++-std::map和已插入数据的行为,我们在StackOverflow上找到一个类似的
有时使用std::vector的起始地址很有用并暂时将该地址视为定期分配缓冲区的地址。例如替换这个:char*buf=newchar[size];fillTheBuffer(buf,size);useTheBuffer(buf,size);delete[]buf;有了这个:vectorbuf(size);fillTheBuffer(&buf[0],size);useTheBuffer(&buf[0],size);这样做的好处当然是缓冲区会自动释放,我不必担心delete[].我遇到的问题是当size==0时。在那种情况下,第一个版本可以正常工作。“分配”了一个空缓冲区,后续函数什么也不
当存储一堆元素并且我不需要随机访问容器时,我使用了std::list这大部分都很好。然而,有时(尤其是当我只是将条目推回后面并且从不删除中间的某个地方时),我希望我有一些具有更好性能的结构来添加条目。std::vector不好是因为:如果它不再适合,它必须重新分配。它不适用于大量数据(因为您不能总是获得非常大的连续空闲内存块)。std::list不好是因为:它对每个push_back进行分配。这很慢并且会导致大量内存碎片。所以,介于两者之间的东西就是我想要的。基本上,我想要类似std::list>的东西或者。或者也许可以代替100,让它成为4096/sizeof(T).也许还有std: