小编Lee*_*hai的帖子

为什么C++ 11从std :: vector的fill构造函数的原型中删除了默认值?

在C++ 98中,std::vector填充构造函数的原型具有初始化程序的默认值.

explicit vector (size_type n, const value_type& val = value_type(),
                 const allocator_type& alloc = allocator_type());
Run Code Online (Sandbox Code Playgroud)

C++ 11使用两个原型.

explicit vector (size_type n);
         vector (size_type n, const value_type& val,
                 const allocator_type& alloc = allocator_type());
Run Code Online (Sandbox Code Playgroud)

(在C++ 14中,填充构造函数再次改变,但这不是这个问题的重点.)

参考链接在这里.

为什么C++ 11会弃用默认的初始化值value_type()

顺便说一句,我尝试编译以下代码clang++ -std=c++11并发出错误,这意味着值类型仍然需要有一个默认构造函数S() {},即默认构造.

#include <vector>

struct S {
    int k;
    S(int k) : k(k) {} // intentionally remove the synthesized default constructor
};

int main() {
    std::vector<S> s(5); // error: no matching …
Run Code Online (Sandbox Code Playgroud)

c++ vector c++11

43
推荐指数
2
解决办法
2792
查看次数

C++中的高效链表?

文件std::list效率低下:

std :: list是一个非常低效的类,很少有用.它为插入其中的每个元素执行堆分配,因此具有极高的常数因子,特别是对于小数据类型.

评论:这让我感到惊讶.std::list是一个双向链表,所以尽管它的元件结构效率低下,它支持插入/删除在O(1)的时间复杂度,但这种功能在此引用的段落完全忽略.

我的问题:说我需要一个连续的小尺寸均匀元素的容器,这种容器应支持元素插入/为O删除(1)复杂性和不并不需要随机存取(虽然支持随机访问是好的,它不是必须的这里).我也不希望堆分配为每个元素的构造引入高常量因子,至少当元素的数量很小时.最后,只有在删除相应的元素时,迭代器才会失效.显然我需要一个自定义容器类,它可能(或可能不)是双向链表的变体.我该如何设计这个容器?

如果无法实现上述规范,那么也许我应该有一个自定义内存分配器,比如说,指针分配器?我知道std::list将分配器作为其第二个模板参数.

编辑:我知道从工程的角度来看,我不应该太关心这个问题 - 足够快就足够了.这只是一个假设的问题,所以我没有更详细的用例.随意放松一些要求!

编辑2:据我所知,O(1)复杂度的两种算法由于其常数因子的不同而具有完全不同的性能.

c++ stl linked-list abstract-data-type dynamic-memory-allocation

42
推荐指数
7
解决办法
7106
查看次数

C++标准提案代码:N和P是什么?

C++标准提案的代码中的"N"和"P"是什么意思?

以下是GCC标准支持状态列表.您可以看到提案类似于"P0245R1"或"N4051"等.(我认为"R"表示"修订").

c++ iso language-lawyer

15
推荐指数
1
解决办法
301
查看次数

如何在if-else语句中使用C++ 20可能/不太可能的属性

这个问题是关于C++ 20的[[likely]]/ [[unlikely]]功能,而不是编译器定义的宏.

这个文档(cppreference)只给出了一个将它们应用于switch-case语句的例子.这个switch-case示例与我的编译器完美编译(g ++ - 7.2),所以我假设编译器已经实现了这个功能,尽管它还没有在当前的C++标准中正式引入.

但是当我像这样使用它们时if (condition) [[likely]] { ... } else { ... },我收到了一个警告:

"警告:语句开头的属性被忽略[-Wattributes]".

那么我应该如何在if-else语句中使用这些属性呢?

c++ gcc-warning c++20

15
推荐指数
3
解决办法
2595
查看次数

如何将 std::vector 转换为 std::span?

std::span 构造函数的文档中,没有一个接受 std::vector 。

那么,这段代码(源页面)是如何编译的?

// createSpan.cpp

#include <algorithm>
#include <iostream>
#include <span>
#include <vector>

int main() {

    std::cout << std::endl;
    std::cout << std::boolalpha;

    std::vector myVec{1, 2, 3, 4, 5};
    
    std::span mySpan1{myVec};                                        // (1)
    std::span mySpan2{myVec.data(), myVec.size()};                   // (2)
    
    bool spansEqual = std::equal(mySpan1.begin(), mySpan1.end(),
                                 mySpan2.begin(), mySpan2.end());
    
    std::cout << "mySpan1 == mySpan2: " << spansEqual << std::endl;  // (3)

    std::cout << std::endl;
    
}
Run Code Online (Sandbox Code Playgroud)

即在 (1) 处调用了 std::span 的哪个构造函数?

c++ c++20

13
推荐指数
1
解决办法
1187
查看次数

C++ SFINAE与decltype:替换失败成为错误?

此代码有效:

// Code A
#include <iostream>
#include <vector>
#include <type_traits>
using namespace std;

template <typename T>
struct S {
    template <typename Iter, typename = typename enable_if<is_constructible<T, decltype(*(declval<Iter>()))>::value>::type>
    S(Iter) { cout << "S(Iter)" << endl; }

    S(int) { cout << "S(int)" << endl; }
};

int main()
{
    vector<int> v;
    S<int> s1(v.begin()); // stdout: S(Iter)
    S<int> s2(1);         // stdout: S(int)
}
Run Code Online (Sandbox Code Playgroud)

但是下面的代码不起作用.在下面的代码中,我只想继承std::enable_if,因此如果所选版本具有成员typedef ,则该类is_iter_of将具有成员typedef .typestd::enable_iftype

// Code B
#include <iostream>
#include <vector>
#include <type_traits>
using …
Run Code Online (Sandbox Code Playgroud)

c++ sfinae

10
推荐指数
2
解决办法
579
查看次数

如何为std :: string定义自定义std :: basic_string <>特化类的Hash类?

我有一个专业化std::basic_string,比如说string_t,它的相同std::string不同之处在于第三个模板参数是我的自定义分配器.

的std :: basic_string的<>

问题:如何使用C++标准库中已提供的散列函数为此专门化定义散列函数类?

我知道如何定义一个Hash仿函数,但我不知道如何利用现有的std::hash<..>仿函数std来定义我的自定义仿函数.我毫不犹豫地写我自己的哈希运算,知道它是重新发明轮子,是不太可能优于std::hash<std::string>,因为之间的唯一区别string_t,并std::string仅仅是分配器.

cppreference有一些例子,但它们对我没有多大帮助 - 我不想std::string使用我的string_t对象的c_str()方法构造一个临时对象,只是std::hash<std::string>为了获取哈希值而将临时对象提供给它,因为它需要分配临时堆内存.

我正在使用C++ 14,我想坚持使用标准库.

c++ string hash c++14

8
推荐指数
1
解决办法
363
查看次数

Google的Breakpad库和crashpad库之间有什么区别?

它们都崩溃了,生成了小型转储供开发人员分析的报告库,并且都是由Google的Chromium项目开发的:

防摔垫

防撞垫

他们的预期用例有什么不同?

minidump google-breakpad

8
推荐指数
2
解决办法
1117
查看次数

为什么LLVM选择开放寻址哈希表来实现llvm::StringMap?

许多消息来源说开放寻址中使用的散列冲突处理方法llvm::StringMap不稳定。当负载因子很高(这是可以想象的)时,据说开放寻址不如链接

但是如果负载因子很低,那么open-addressing就会有巨大的内存浪费,因为我必须在内存中分配Bucket_number * sizeof(Record)字节,即使大多数bucket没有记录。

所以我的问题是,LLVM 选择开放寻址而不是单独链接的原因是什么?是否仅仅是因为缓存局部性(记录本身存储在存储桶中)获得的速度优势?

谢谢:)

编辑:C++11 标准对链接方法的要求,std::unordered_setstd::unordered_map不是开放寻址。为什么LLVM会选择一种连C++标准都达不到的hash碰撞处理方式?llvm::StringMap 是否有任何特殊用例可以保证这种偏差?(编辑:这张幻灯片比较了几种 LLVM 数据结构与 STL 对应数据结构的性能)

另一个问题,顺便说一句:

如何llvm::StringMap保证键的哈希值在增长时不会重新计算?该手册说:

哈希表增长不会重新计算表中已有字符串的哈希值。

c++ hash hashmap llvm data-structures

6
推荐指数
1
解决办法
706
查看次数

LLVM代码生成器:机器代码表示与机器无关吗?

请注意:这个问题不是关于LLVM IR,而是LLVM的MIR,一个低于前者的内部中间表示.

关于LLVM 机器代码描述类的文档说明(突出我的):

在高级别,LLVM代码被转换为由MachineFunction,MachineBasicBlock和MachineInstr实例构成的机器特定表示...

然而,同一段落继续说:

这种表示完全是目标不可知的,以最抽象的形式表示指令......

我的问题是,如何理解这一段?

我很难协调这个中间表示是机器特定的并且同时与目标无关的声明.在LLVM的上下文中,我认为"机器"和"目标"意味着相同的东西 - 编译的可执行文件使用的指令集架构(例如x86_64,MIPS).

欢迎举例.

llvm compiler-optimization

6
推荐指数
1
解决办法
86
查看次数