小编ada*_*603的帖子

为什么不能从unique_ptr构造weak_ptr?

如果我理解正确,a weak_ptr不会增加托管对象的引用计数,因此它不代表所有权.它只是让您访问一个对象,其生命周期由其他人管理.所以我真的不明白为什么一个weak_ptr不能用a构建unique_ptr,而只能用a 构建shared_ptr.

有人能简单解释一下吗?

c++ smart-pointers shared-ptr weak-ptr unique-ptr

50
推荐指数
6
解决办法
2万
查看次数

Perf显示损坏的函数名称

在我看到CppCon 2015的这个演讲之后,我想对一些程序进行概述.我下载了那个人在谈话中使用的相同Google基准库,用适当的开关编译我的程序,将其链接到它,然后使用perf记录一次跑步.报告选项给了我这个:

在此输入图像描述

正如您所看到的,函数名称不是很易读.我认为这与C++名称修改有关.有趣的是,所有的功能名称都在视频中正确显示给那个发表演讲的人,但不适合我.我不认为这是完全缺少符号信息的情况,因为在这种情况下我只会看到内存地址.由于某种原因,perf不能"撤消"我的C++名称,这看起来很令人沮丧.

我正在使用gcc(g ++)版本5.2.1,perf是版本4.2.6,我在编译时使用这些开关:

-I<my own include path> -L<path to the benchmark library> -O3 -std=c++14 -gdwarf-2 -fno-rtti -Wall -pedantic -lbenchmark -pthread

我不使用的原因-fno-omit-frame-pointer是我使用了-gdwarf-2选项,它将调试信息留在矮人可执行文件中,这是在这种情况下保留帧指针的替代方法.这也意味着我--call-graph "dwarf"转到了perf record.无论如何,我也尝试了帧指针方法,它给出了相同的结果,所以这并不重要.

那么为什么在这种情况下不会"撤消"C++名称错误?这与使用GCC有什么关系,这当然意味着我正在使用libstdc ++?

c++ profiling name-mangling perf

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

使用C风格的字符串文字与构造未命名的std :: string对象的默认建议?

因此,C++ 14引入了许多用户定义的文字,其中一个是用于创建对象的"s"文字后缀std::string.根据文档,它的行为与构造std::string对象完全相同,如下所示:

auto str = "Hello World!"s; // RHS is equivalent to: std::string{ "Hello World!" }
Run Code Online (Sandbox Code Playgroud)

当然,构建一个未命名的std::string对象可以在C++ 14之前完成,但由于C++ 14的方式简单得多,我认为实际上会有更多的人考虑std::string在现场构建对象,这就是为什么我认为有必要提问这个.

所以我的问题很简单:在什么情况下构建一个未命名的std::string对象是一个好的(或坏的)想法,而不是简单地使用C风格的字符串文字?


例1:

考虑以下:

void foo(std::string arg);

foo("bar");  // option 1
foo("bar"s); // option 2
Run Code Online (Sandbox Code Playgroud)

如果我是正确的,第一个方法将调用适当的构造函数重载std::string来在foo范围内创建一个对象,第二个方法将首先构造一个未命名的字符串对象,然后foo从中移动构造的参数.虽然我确信编译器非常擅长优化这样的东西,但是,第二个版本似乎需要额外的移动,而不是第一个替代(当然不像移动是昂贵的).但同样,在使用合理的编译器编译之后,最终结果最有可能被高度优化,并且无论如何都没有冗余和移动/复制.

另外,如果foo被重载以接受右值引用怎么办?在那种情况下,我认为打电话是有意义的foo("bar"s),但我可能是错的.


例2:

考虑以下:

std::cout << "Hello World!" << std::endl;  // option 1
std::cout << "Hello World!"s << std::endl; // option 2
Run Code Online (Sandbox Code Playgroud)

在这种情况下,std::string对象可能cout通过右值引用传递给运算符,第一个选项可能传递指针,因此两者都是非常便宜的操作,但第二个选项首先需要额外构建对象.这可能是一种更安全的方式(?). …

c++ string c-strings stdstring string-literals

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

如何枚举Sprite Kit场景中的所有节点?

我想枚举场景中的所有节点.不仅是场景本身的孩子,还有那些孩子,以及那些孩子的孩子......所以我希望能够通过整个节点层次结构.

有没有一种方法可以在不知道节点树有多深的情况下做到这一点?

objective-c ios sprite-kit

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

为什么gcc在这个递归的斐波那契代码中生成比clang更快的程序?

这是我测试的代码:

#include <iostream>
#include <chrono>
using namespace std;

#define CHRONO_NOW                  chrono::high_resolution_clock::now()
#define CHRONO_DURATION(first,last) chrono::duration_cast<chrono::duration<double>>(last-first).count()

int fib(int n) {
    if (n<2) return n;
    return fib(n-1) + fib(n-2);
}

int main() {
    auto t0 = CHRONO_NOW;
    cout << fib(45) << endl;
    cout << CHRONO_DURATION(t0, CHRONO_NOW) << endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当然,有更快的方法来计算斐波纳契数,但这是一个很好的小压力测试,专注于递归函数调用.除了使用计时器测量时间之外,代码没有别的了.

首先,我在OS X上的Xcode中运行了几次测试(这样就是铿锵声),使用-O3优化.跑了大约9秒钟.

然后,我在Ubuntu上使用gcc(g ++)编译了相同的代码(再次使用-O3),该版本只用了大约6.3秒就可以运行了!此外,我在我的Mac上运行VirtualBox内部的 Ubuntu ,这只会对性能产生负面影响,如果有的话.

你去吧:

在OS X上克服 - > ~9秒

在VirtualBox中的 Ubuntu 上的 gcc - > ~6.3秒.

我知道这些是完全不同的编译器,所以他们做的事情不同,但我看到的所有gcc和clang的测试只显示出更少的差异,在某些情况下,差异是另一种方式(clang更快) ).

因此,在这个特定的例子中,为什么gcc能够以英里数击败?

c++ x86 gcc clang compiler-optimization

7
推荐指数
2
解决办法
601
查看次数

处理多个客户端的单个TCP/IP服务器(用C++编写)?

我想写C++中的TCP/IP服务器(使用bind(),accept()可以处理多个客户端连接到它在同一时间等).我已经阅读了一些关于此的主题,每个人都建议如下(脏的伪代码即将出现):

set up server, bind it

while (1) {
    accept connection
    launch new thread to handle it
}
Run Code Online (Sandbox Code Playgroud)

哪个在具有多个线程的机器上完全正常工作.但我的目标系统是没有任何硬件线程的单核机器.为了进行一点测试,我尝试std::thread在系统上启动多个线程,但它们是一个接一个地执行的.没有平行的善良:(

这使得无法实现上述算法.我的意思是,我确信它可以完成,我只是不知道如何,所以我真的很感激任何帮助.

c++ sockets networking multithreading tcp

5
推荐指数
2
解决办法
2万
查看次数

为什么clang中的-O2或更高优化会破坏这段代码?

我在网站上检查了类似的问题,但我找不到符合我的情况的任何内容.这是我试图运行的代码(需要C++ 14):

#include <iostream>
#include <chrono>
#include <thread>
using namespace std;

class countdownTimer {
public:
    using duration_t = chrono::high_resolution_clock::duration;

    countdownTimer(duration_t duration) : duration{ duration }, paused{ true } {}

    countdownTimer(const countdownTimer&)               = default;
    countdownTimer(countdownTimer&&)                    = default;
    countdownTimer& operator=(countdownTimer&&)         = default;
    countdownTimer& operator=(const countdownTimer&)    = default;

    void start() noexcept {
        if (started) return;
        startTime = chrono::high_resolution_clock::now();
        endTime = startTime + duration;
        started = true;
        paused = false;
    }

    void pause() noexcept {
        if (paused || !started) return;
        pauseBegin = chrono::high_resolution_clock::now();
        paused …
Run Code Online (Sandbox Code Playgroud)

c++ clang compiler-optimization c++-chrono c++14

5
推荐指数
2
解决办法
557
查看次数

为什么VS和gcc在这里调用不同的转换运算符(常量与非常量)?

这段代码当然是愚蠢的,但是我只是为了说明问题编写了代码。这里是:

#include <iostream>
using namespace std;

struct foo {
    int a = 42;

    template <typename T>
    operator T* () {
        cout << "operator T*()\n";
        return reinterpret_cast<T*>(&a);
    }

    template <typename T>
    operator const T* () const {
        cout << "operator const T*() const\n";
        return reinterpret_cast<const T*>(&a);
    }

    template <typename T>
    T get() {
        cout << "T get()\n";
        return this->operator T();
    }
};

int main() {
    foo myFoo;
    cout << *myFoo.get<const int*>() << '\n';
}
Run Code Online (Sandbox Code Playgroud)

使用Visual Studio 2019(ISO C ++ 17,/Ox …

c++ const operator-overloading operator-keyword

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

为什么在这种情况下不是最合适的构造函数?

考虑以下课程:

class foo {
    int data;
public:
    template <typename T, typename = enable_if_t<is_constructible<int, T>::value>>
    foo(const T& i) : data{ i } { cout << "Value copy ctor" << endl; }

    template <typename T, typename = enable_if_t<is_constructible<int, T>::value>>
    foo(T&& i) : data{ i } { cout << "Value move ctor" << endl; }

    foo(const foo& other) : data{ other.data } { cout << "Copy ctor" << endl; }

    foo(foo&& other) : data{ other.data } { cout << "Move ctor" << endl; …
Run Code Online (Sandbox Code Playgroud)

c++ constructor type-conversion copy-constructor enable-if

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

static_cast与直接调用转换运算符?

考虑以下类,就像一个简单的例子:

#include <iostream>
#include <string>
using namespace std;

class point {
public:
    int _x{ 0 };
    int _y{ 0 };

    point() {}
    point(int x, int y) : _x{ x }, _y{ y } {}
    operator string() const
        { return '[' + to_string(_x) + ',' + to_string(_y) + ']'; }

    friend ostream& operator<<(ostream& os, const point& p) {

        // Which one? Why?
        os << static_cast<string>(p); // Option 1
        os << p.operator string();    // Option 2

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

是否应该直接调用转换运算符,或者只是调用static_cast …

c++ casting static-cast conversion-operator

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

Swift中的正常数组vs'NSMutableArray'?

所以在Swift中,有什么区别

var arr = ["Foo", "Bar"] // normal array in Swift
Run Code Online (Sandbox Code Playgroud)

var arr = NSMutableArray.array() // 'NSMutableArray' object

["Foo", "Bar"].map {
    arr.addObject($0)
}
Run Code Online (Sandbox Code Playgroud)

除了是同一件事的不同实现.两者似乎都具有可能需要的所有基本功能(.count插入/移除对象等的能力).

NSMutableArray是在Obj-C时代发明的,显然是为了提供更现代的解决方案,而不是常规的C风格阵列.但它与Swift的内置阵列相比如何呢?

哪一个更安全和/或更快?

arrays performance nsmutablearray swift

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

删除std :: shared_ptr而不破坏托管对象?

我在以下场景中:

struct container {
    data* ptr;
};

void someFunc(container* receiver /* wants to be filled */) {
    auto myData = createData(); // returns shared_ptr<data>
    receiver->ptr = myData.get();
}
Run Code Online (Sandbox Code Playgroud)

生成该数据的函数和接收它的对象是两个不同库的一部分,我无法修改它的源代码.我必须使用这些数据类型,我无能为力.

所以我必须实现一个获取一些数据的函数,然后将指向该数据的指针传递给一个对象.我的问题是创建我的数据的函数,返回一个shared_ptr实例.需要数据的对象只接受指向它的原始指针.

如您所见,我调用get()shared_ptr来获取原始指针并将其传递给接收对象.如果我没有弄错,那么shared_ptr只要它超出范围,就会减少引用计数.所以在这种情况下,这意味着它会在函数返回时立即销毁我的数据,因为引用计数将达到0.

那么如何在shared_ptr不破坏托管对象的情况下摆脱实例呢?我传递数据的对象(为简单起见用"容器"结构说明)确实在其析构函数中处理内存清理,因此我不需要任何引用计数或类似的东西.我不想再监视分配的数据(除了接收指向它的指针的对象).我想摆脱它shared_ptr,并且只有一个指向已分配数据的原始指针,我可以将其传递给接收对象.

那可能吗?

c++ smart-pointers shared-ptr

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

类数据成员的破坏顺序?

想象一下这样的一个类:

class foo {
public:
    foo() : _bar{new bar}, _baz{new baz} {}
private:
    unique_ptr<bar> _bar;
    unique_ptr<baz> _baz;
};
Run Code Online (Sandbox Code Playgroud)

因此,每当一个foo被破坏的实例被破坏时,它的数据成员将以什么顺序被销毁,如果这个被定义的行为呢?

让我们说这_baz取决于它的存在_bar,也许它使用了一些_bar拥有的资源(让我们假设它知道_bar对象,即使构造函数没有反映这一点).所以在这种情况下,如果_bar首先被破坏(当它被破坏的时候foo),那么_baz可能会尝试访问已经被_bar析构函数释放的一些资源.

一个显而易见的解决方案是实现一个析构函数foo,它可以手动释放_baz并按_bar正确的顺序,但是如果没有实现析构函数呢?是否存在定义数据成员的销毁顺序的默认行为?

c++ destructor operator-precedence

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