小编NoS*_*tAl的帖子

是否将地图大小作为值插入到地图未定义行为中?

编辑:这个问题不应该被关闭,如果你查看答案,你会发现它们完全不同(旧问题没有提到 C++17)。

我正在阅读一篇 PVS博客文章,他们提到了以下错误。

(减少)

std::map<int,int> m;
m[7]=5;
auto val = 15;
if (!m.contains(val)){
    m[val] = m.size(); // bug here
}
Run Code Online (Sandbox Code Playgroud)

根据博客文章,这是错误的。我一直认为 operator [] 对 map 的调用是一个函数调用,所以 .size() 在 [] 之前被排序,因为函数充当序列点。

那么为什么这是一个错误呢?

注意:我知道从 C++11 开始就不存在序列点,但我使用它们是因为新的措辞对我来说更难理解。

c++ sequence-points unspecified-behavior

4
推荐指数
1
解决办法
103
查看次数

在哪些情况下 std::optional operator == 会导致未定义的行为?

Cppreference对 的混合(可选和一些其他非可选类型)比较运算符的描述std::optional如下:

将 opt 与一个值进行比较。仅当 opt 包含值时才比较值(使用 T 的相应运算符)。否则,opt 被认为小于 value。如果 *opt 和 value 之间对应的双向比较表达式格式不正确,或者其结果不能转换为 bool,则行为未定义。

这里让我感到困惑的是:

  • 这些格式不正确的比较的例子是什么?

  • 为什么编译器/STL 不拒绝无效的比较而不是给我们 UB?

c++ c++17 stdoptional

4
推荐指数
1
解决办法
269
查看次数

C++20 中是否有assign_or_inserter/insert_or_assigner?

std::inserter 遇到的问题是,如果键已经存在,它会调用 map 的 insert 为 noop。有std::map::insert_or_assign,但我找不到使用它的插入器。

C ++ 20中有这样的东西吗?

注意:我知道我可以从 SO/互联网上的某个地方 c/p 它,我对 STL/boost 解决方案感兴趣,而不是从某个地方的 c/p 实现。

c++ stdmap c++20

4
推荐指数
1
解决办法
122
查看次数

为什么我不能将指定的初始化器与不是聚合的结构一起使用?

C++ 有一个不错的新特性:

struct Point{
int x;
int y;
int z; 
};

Point p{.x=47, .y=1701, .z=0};
Run Code Online (Sandbox Code Playgroud)

但是如果我添加一个构造函数,那么我将被禁止使用漂亮的指定初始化器语法:

struct Point{
Point(int x, int y, int z = 0): x(x), y(y), z(z){}
int x;
int y;
int z; 
};

static Point p{.x=47, .y=1701, .z = 0};
Run Code Online (Sandbox Code Playgroud)

错误:指定的初始值设定项不能与非聚合类型“Point”一起使用

我是否遗漏了一些明显的东西(为什么如果指定的初始化器与具有公共成员但不是聚合的结构/类一起工作会很糟糕)或者这只是一个没有添加到标准中的缺失功能?

c++ designated-initializer c++20

4
推荐指数
2
解决办法
309
查看次数

x!=x 是实现 std::isnan() 的合法方式吗

尽管 Microsoft 博客声称std::isnan在我的代码中使用其他方式仍然会生成对 c++ 运行时而不是 inlined 的调用ucomiss。现在我用x!=xcheck解决了这个问题(因为在这段代码中性能对我很重要),但这让我想知道......如果x!=x是一种检查 NaNess 的方法,这不是一种简单的实现方法std::isnan吗?

但据我所知,gcc/clang 使用内在函数(并且 msvc 正在尝试)。如果它可以作为正常功能有效实现,他们为什么要打扰?

所以我有点困惑,因为SO 上的一个答案声称这是自我比较可以返回错误的唯一方法。

c++ optimization stl visual-c++

4
推荐指数
1
解决办法
94
查看次数

C++ 概念可以用于在 C++ 中实现混合类型 min 和 max 吗?

您可能知道std::maxstd::min“受苦”,因为它们有 1 个模板参数,因此即使简单max(container.size(), 47)也行不通,因为 .size() 返回size_t而 47 是int

我知道历史上曾有人提议向 C++ 添加适当的重载,但被拒绝了。但据我所知,这主要是由于纸张过于复杂而无法获得足够的收益,所以我想知道是否可以将其std::common_range_t用作返回值(发明的类型特征使您的 int/float 足够大以容纳混合参数的最小值/最大值,否则会出现硬错误)那会好吗...

所以最终得到我的问题:如果我们希望 min/max 扩展为采用 2 如上所述的模板参数,是否有任何向后兼容性或任何其他问题阻止了这一点?

笔记:

  • 这主要是技术上可能的问题,我对 WG21 是否计划做任何事情来标准化这个问题感兴趣,主要是对潜在的技术限制感到好奇。
  • 这个问题的 C++17 版本(由于某种原因被严重低估),但更一般的是,还涉及其他一些限制。

c++ c++-concepts c++20

4
推荐指数
1
解决办法
98
查看次数

为什么 C++ 禁止前向声明非模板 std:: 类型?

C++ 标准不允许代码在名称空间中转发声明类std,即使它们不是模板。

我看不出这样做的充分理由,所以我想知道动机是什么?

这可能是一个巨大的编译时间改进。例如,std::mutex这是一个简单的类,但<mutex>标头拖入了大量内容(至少在我的实现中)。

如果有人想知道为什么我要区分模板和非模板,那么这是因为模板实例化可能根据提供的模板参数而存在显着差异,所以我想这可能更难以实现/支持。

c++ forward-declaration c++20

4
推荐指数
1
解决办法
252
查看次数

C++20 中不允许结构模板重载的设计原因是什么?

在回答我之前的问题时,我了解到 C++ 20 概念不允许重载结构模板参数,例如这不起作用:

#include <concepts>

template <std::integral>
struct S{

};
template <std::floating_point>
struct S{
};
Run Code Online (Sandbox Code Playgroud)

对于好奇的 clang 错误是类似的,但这并不重要,因为我知道 C++ 标准不允许此代码工作:

模板重新声明中的类型约束不同

我发现这种编写模板的非工作方式非常自然,所以我想知道是否曾经考虑过这一点,如果是的话,为什么它在标准化过程中被拒绝?

PS 这似乎在 C++20 中有效,但我发现它丑陋得多

#include <concepts>
#include <iostream>

template <typename T>
requires std::integral<T> || std::floating_point<T>
struct S{

};
template <std::integral T>
struct S<T>{
    static constexpr char msg[] = "i";

};
template <std::floating_point T>
struct S<T>{
    static constexpr char msg[] = "fp";
};

int main() {
    std::cout <<  S<char>::msg << std::endl;
    std::cout <<  S<double>::msg << std::endl; …
Run Code Online (Sandbox Code Playgroud)

c++ c++-concepts c++20

4
推荐指数
2
解决办法
385
查看次数

在c ++中是否有一种方法可以确保类成员函数不会更改任何类数据成员?

让我们说我有一个

class Dictionary
{
vector<string> words;  
void addWord(string word)//adds to words
{
/...
}
bool contains(string word)//only reads from words
{
//...
}
}
Run Code Online (Sandbox Code Playgroud)

有没有办法使编译器检查包含不更改单词向量.Ofc这只是一个类数据成员的例子,我希望它能与任意数量的数据成员一起使用.PS我知道我没有公开:私有:我故意把它留下来让代码更短,问题更清晰.

c++ syntax

3
推荐指数
2
解决办法
196
查看次数

有没有一种方法在c ++中初始化一些类对象的数组而不首先定义大小

我使用这样的代码:

const vector<filterStat> someArray={
        {"Ana",1},
        {"Bob",2},
        {"Charlie",5},
};
static const int knElements=filterStats.size();
Run Code Online (Sandbox Code Playgroud)

忽略kn前缀,这是我说的不变,大小的方式.我发现它很有用,因为我不必在更改向量的初始化时更改或计算knElements.但问题是使用const向量困扰我,因为向量是可调整大小的数组,因此感觉不对.顺便说一句,如果你想知道为什么我需要它 - 长故事,它是一种地图,但我不做任何搜索或插入,只是"为每个"所以阵列是最好的选择.

编辑:我改变了我的鳕鱼,它编译:

const   filterStat filterStats[]={
//...
};

static const int knFilterStats=sizeof(filterStats)/sizeof(filterStats[0]);
static_assert(sizeof(filterStats),"Can't run statistics-no filterStats exists");
Run Code Online (Sandbox Code Playgroud)

我不知道你可以用c ++做[].抱歉愚蠢的问题,我希望它对某人有所帮助.

c++ arrays c++11

3
推荐指数
1
解决办法
104
查看次数