小编Tel*_*ope的帖子

当使用 std::make_pair 从函数返回一对时,为什么结构化绑定不会发生 RVO?

考虑这段代码,它定义了一个简单的结构Test(带有默认构造函数和复制构造函数)并std::pair <Test, Test>从函数返回 a 。

#include <iostream>
#include <utility>

using namespace std;

struct Test {
    Test() {}
    Test(const Test &other) {cout << "Test copy constructor called\n";}
};

auto func() {
    return make_pair(Test(), Test());
}

int main()
{
    auto [a, b] = func(); // Expectation: copies for a and b are both elided

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

令人惊讶的是,输出是

Test copy constructor called
Test copy constructor called
Run Code Online (Sandbox Code Playgroud)

而修改func

Test copy constructor called
Test copy constructor called
Run Code Online (Sandbox Code Playgroud)

导致复制构造函数未被调用。我的 …

c++ return-value-optimization copy-elision c++17

17
推荐指数
3
解决办法
774
查看次数

有没有办法不使用命名空间中的项目?

我学会了打字

using namespace std;
Run Code Online (Sandbox Code Playgroud)

在程序开始时是一个坏习惯,因为它包含命名空间中的每个函数。如果存在名称冲突,这可能会导致错误。

我的问题是,不存在于指定的命名空间功能,你一个方法,希望使用?是否有一些声明,例如

not_using std::cin;
Run Code Online (Sandbox Code Playgroud)

可以做到这一点吗?

c++ namespaces std

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

是UB将T*转换为uintptr_t,将uintptr_t重新转换为void*,然后将void*静态转换回T*吗?

我正在编写一个 C++ 标记指针。我有一个问题,我用来实现其基本功能的操作是否会导致未定义的行为:

  • 当给定一个指针构造一个标记指针时T*,我reinterpret_cast将指针指向 a uintptr_t。这允许我对内存地址执行按位操作,这是添加/提取/检查标签所必需的。
  • 当用户请求返回原始指针时,我将 强制reinterpret_cast转换uintptr_t为 a void*(删除标签后)。如果需要指向特定类型的指针,我会将其接受 (void*假设确实是标记指针中保存的类型)。static_castT*T

因此,总而言之,我正在对 a 执行以下转换T*

  • reinterpret_cast荷兰国际集团T*到auintptr_t
  • 稍后,reinterpret_cast将其uintptr_t转为 a void*,并可能static_cast将其void*转回 a T*

这是否会导致未定义的行为?此外,我是否在预期的用例中正确使用了reinterpret_cast和?static_cast

c++ pointers static-cast memory-address reinterpret-cast

6
推荐指数
0
解决办法
326
查看次数

`std::mt19937` 静态函数变量是线程安全的吗?

我有一个函数,它使用类型为 的静态函数变量rand_double()生成随机浮点值。多个线程可以同时使用该函数。std::mt19937

#include <random>

auto random_double(double min, double max) {
    static std::mt19937 generator{std::random_device{}()}; // Forgot to seed it, thanks @user4581301
    return std::uniform_real_distribution<>{min, max}(generator);
}
Run Code Online (Sandbox Code Playgroud)

我的第一个问题是,上面的代码是线程安全的吗?我知道从C++11开始,静态函数变量的初始化始终是线程安全的,但是并发使用生成器怎么样?

c++ random thread-safety c++20 mt19937

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

如果条件不相关,我应该更喜欢两个 if 语句而不是 if-else 语句吗?

所以我知道一般来说,我应该更喜欢else-ifover 和if if。但是如果这两个条件不相关呢?例如,这些将被视为“相关”条件:

if (line[a] == '{'){
    openCurly = true;
}
else if (line[a] == '}'){
    closeCurly = false;
}
Run Code Online (Sandbox Code Playgroud)

注意 if 语句中的两个条件是如何关联的,当一个是 时true,另一个必须是false。这是因为line[a]可以是{}不是两者都可以。

这是另一个例子:

if (line[a] == '{')
{
    openCurly = true;
}
else if ((line[a] == ';' && !openCurly) || (line[a] == '}' && openCurly))
{
    DoSomething(line);
    line = "";
}
Run Code Online (Sandbox Code Playgroud)

如果第一个条件为真,则第二个条件永远不会评估为真,因此有一个else-if. 但是,这两个条件看起来大不相同。

那么,我应该更喜欢这样的东西吗?

if (line[a] == '{')
{
    openCurly = true; …
Run Code Online (Sandbox Code Playgroud)

c++ if-statement

2
推荐指数
1
解决办法
123
查看次数

是否可以恢复“std::span”中元素的实际索引?

我有一个带有成员变量的类std::vector。我还有一个成员函数,它采用std::vector由两个size_t参数指定的连续范围,并对其执行一些操作。

class MyClass {
    std::vector<int> objects;

public:

    void func(size_t start_index, size_t end_index); 
}
Run Code Online (Sandbox Code Playgroud)

现在,我想size_t用单个参数替换两个std::span参数,以提高安全性、可读性和可维护性。然而,有一个障碍:在我的函数中,我需要能够恢复原始std::vector. 就像这样,我需要能够找到std::span原始数组中的开始位置。有没有办法做到这一点?如果没有,那么我是否别无选择,只能使用我原来笨重的设计?

objects.begin()(我最初尝试通过从我拥有的参数begin()的迭代器中减去来恢复第一个索引std::span,但这导致了编译错误。)

c++ stdvector c++20 std-span

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

具有 lambda 比较器的 std::priority_queue 的 std::swap 在 C++20 下编译,但不在 C++17 下编译:“错误:无法分配 value_compare 类型的对象”

以下代码(有std::swap两个std::priority_queue<int, std::vector<int>, decltype(some lambda)>s)会在 C++17 中导致编译器错误,但在 C++20 中不会导致编译器错误。

#include <queue>

int main()
{
    auto cmp = [](int x, int y) {return x > y;};
    std::priority_queue<int, std::vector<int>, decltype(cmp)> pq1(cmp), pq2(cmp);
    std::swap(pq1, pq2); // adding this line results in an error
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

C++17下的错误是

error: object of type 'value_compare' (aka '(the lambda cmp)') cannot be assigned because its copy assignment operator is implicitly deleted
    {c = _VSTD::move(__q.c); comp = _VSTD::move(__q.comp); return *this;}

note: in instantiation of member …
Run Code Online (Sandbox Code Playgroud)

c++ swap priority-queue c++17 c++20

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

(C++) 多维向量中元素的总数

我了解到检查一维向量的大小是一项简单的任务,因为你可以只写

#include <iostream>
#include <vector>

int main(){
    vector <int> v = {1, 2, 3, 4};
    cout << v.size() << endl;
    cout << sizeof(v)/sizeof(int) << endl;
}
Run Code Online (Sandbox Code Playgroud)

正如预期的那样,输出为 4。

但是,当我对多维向量尝试相同的方法时,结果并不是我认为正确的:

#include <iostream>
#include <vector>

int main(){
    vector <vector<int>> v = {{1, 2}, {3, 4}, {5}}; // 5 elements in total
    cout << v.size() << endl;
    cout << sizeof(v)/sizeof(int) << endl;
}
Run Code Online (Sandbox Code Playgroud)

这次,输出是 3 而不是预期的 5。有人可以解释为什么会发生这种情况,以及如何修改代码以产生正确的输出?

c++ vector c++11

0
推荐指数
1
解决办法
109
查看次数

使用完数据结构后清空数据结构是个好习惯吗?

我在编程中使用了各种数据结构,我经常将数据从一种结构转移到另一种结构。

// assume that I want to transfer all data from v to Q
vector <int> v = {1, 2, 3, 4};
queue <int> Q;

for(int item : v){
    Q.push(item);
}
// after this point, v is no longer used
Run Code Online (Sandbox Code Playgroud)

使用完结构后,清空它是一个好习惯吗?例如,在上面的代码中,我应该v = {};在最后一条评论后输入吗?

c++ data-structures

0
推荐指数
1
解决办法
55
查看次数

为什么 C++ 编译器在创建机器代码之前将源代码翻译成汇编?

我开始学习C++,我了解到编译器通过编译将源代码从程序转换为机器代码。

但是,我了解到 C++ 编译器实际上将源代码转换为程序集,作为将程序集代码转换为机器代码之前的中间步骤。这一步的目的是什么?

c++ assembly

0
推荐指数
1
解决办法
292
查看次数

将弧度转换为度数时失去精度

我有双数据类型的弧度值x

x = 0.423438990337458964763328594926861114799976348876953125;

将此值转换为度然后再转换回弧度时,我希望计算机在x不损失精度的情况下给我相同的值。

我正在使用该qRadiansToDegrees方法qt,它看起来很完美,但是在尝试访问x.

如果这是可以解决的,有人可以告诉我如何防止这种情况发生吗?如果不是,是否有另一种表示方式,doubles以便它们在转换后不会失去精度?

c++

0
推荐指数
1
解决办法
262
查看次数

为什么增加 long long 比增加 int 慢得多?

我最近很想知道 C++ 可以在一秒钟内大致处理多少整数增量。为了测试这一点,我编写了一个简短的驱动程序,如下所示:

#include <iostream>

using namespace std;

int main()
{
    int num = 0;
    while(++num) {
        if(num%100000000 == 0) { // prints num every 100 million iterations
            cout << num << endl;
        }
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我在 g++ 7.5.0 下用优化 -O3 编译这段代码时,程序设法每秒增加大约 800,000,000 次。

但是当我将 a 的类型切换int到 a 时long long,我发现性能严重下降,每秒大约 100,000,000 次。

有人可以解释为什么会出现这种差异吗?

c++ integer

0
推荐指数
1
解决办法
67
查看次数