小编Lem*_*rop的帖子

为什么移动std :: optional不会重置状态

我很惊讶地得知移动构造函数(以及该事项的赋值)std::optional没有重置可选的移动,如[19.6.3.1/7]中所示,其中"bool(rhs)不变".

这也可以通过以下代码看出:

#include <ios>
#include <iostream>
#include <optional>
#include <utility>

int main() {
  std::optional<int> foo{ 0 };
  std::optional<int> bar{ std::move(foo) };

  std::cout << std::boolalpha
            << foo.has_value() << '\n'  // true
            << bar.has_value() << '\n'; // true
}
Run Code Online (Sandbox Code Playgroud)

这似乎与在标准库中移动的其他实例相矛盾,例如移动std::vector容器的位置通常以某种方式重置(在向量的情况下保证之后为空)以使其"无效",即使其中包含的对象也是如此他们自己已经离开了.这个或潜在的用例是否有任何理由支持,例如可能试图模仿相同类型的非可选版本的行为?

c++ optional c++17

20
推荐指数
3
解决办法
1793
查看次数

C++与类成员变量的线程访问问题

在使用线程一段时间后,我遇到了一种情况,我需要一个线程永远运行,直到调用一个函数(或任何类型的事件).为此,我创建了一个bool值来控制线程执行的函数内部的while循环,但我很快注意到在线程开始运行后外部变量没有更新,导致线程在被要求时永远不会停止.

下面是一些代表问题的简单代码:

#include <cstdio>
#include <thread>
#include <chrono>

class A {
public:
    A();

    void startThread();
    void endThread();
private:
    void threadCall();
    bool active;
};

int main() {
    A threadThing;
    threadThing.startThread();
    printf("[M] Thread Created\n");
    std::this_thread::sleep_for(std::chrono::seconds(5));
    threadThing.endThread();
    printf("[M] Thread Killed\n");
    std::this_thread::sleep_for(std::chrono::seconds(5));

    return 0;
}

A::A() {
    active = false;
}

void A::startThread() {
    active = true;
    std::thread AThread(&A::threadCall, *this);
    AThread.detach();
}

void A::endThread() {
    active = false;
}

void A::threadCall() {
    printf("[T] Thread Started\n");
    while (active) {
        std::this_thread::sleep_for(std::chrono::seconds(2));
    }
    printf("[T] Thread Ended\n");
} …
Run Code Online (Sandbox Code Playgroud)

c++ multithreading

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

使用C++中的浮点数的Memcpy

我遇到的问题似乎是非常简单的代码,但它完全符合我的期望:

码:

char b[sizeof(float)];
float a = 1.5f;
memcpy(b, &a, sizeof(float));
printf("%f\n", b[0]);
Run Code Online (Sandbox Code Playgroud)

输出:

62827075002794546937726511559700164562271693617156259118887055013962964939146547
22493354730179062365918845182857228200743453702107162763566167344423902681816648
14169764096333089859051972349071751428406066879715295195780847944297207011246001
33742258486014791122944.000000
Run Code Online (Sandbox Code Playgroud)

然而,当我这样做时它起作用:

char b[sizeof(int)];
int a = 3;
memcpy(b, &a, sizeof(int));
printf("%i\n", b[0]);
Run Code Online (Sandbox Code Playgroud)

输出:

3
Run Code Online (Sandbox Code Playgroud)

为什么会这样?是因为字节序还是其他什么?

c++ memcpy

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

std :: is_constructible即时上下文和朋友声明

最近,我尝试检测特定私有构造函数的存在,并遇到了std::is_constructible仅检查即时上下文而无法识别任何此类构造函数的问题。经过一些研究,我确实看到这里的一个答案提到,正确的方法是与有问题的班级交朋友,std::is_constructible以使其可以访问。

为了测试此方法是否有效,我尝试了以下测试代码

#include <type_traits>

class A {
private:
  template<typename, typename ...>
  friend struct std::is_constructible;

  A() = default;
};

int main() {
  static_assert(std::is_constructible<A>::value);
  static_assert(std::is_constructible_v<A>);
}
Run Code Online (Sandbox Code Playgroud)

有趣的是,此方法std::is_constructible在Visual Studio 2017中似乎可以使用,尽管随后我开始遇到的问题std::is_constructible_v。在他们的实现中,std::is_constructible他们没有在实际的结构本身上使用别名模板,而是直接调用内部使用的内在函数,而内在函数又忽略了好友声明。

认为这是其标准库实现中的一个错误,然后我在其他编译器中进行了测试,发现无论是clang还是gcc在任何情况下都不能传递此断言,这使我想知道它是否应该像这样完全起作用(链接文章上的某些评论似乎暗示这是一个错误,而其他人则表示不应考虑朋友声明)。

因此,主要的问题是该代码是否应该正常工作(因为它应该能够访问私有构造函数并传递断言),并且该方法将标准定义的访问限制为立即上下文?这里也提出类似的问题,我不确定的主要事情是这种情况下“即时上下文”所意图的确切定义,因为这与链接问题中的示例稍有不同。

N4713 23.15.4.3.8 [meta.unary.prop] / 8的相关段落:

就像在与T和任何Arg不相关的上下文中一样,执行访问检查。仅考虑变量初始化的即时上下文的有效性。

c++ type-traits language-lawyer c++17

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