小编Far*_*nor的帖子

为什么编译器现在接受在从 std::stringstream::operator<<() 返回的 std::ostream& 上调用 str() 成员?

考虑以下行:

std::string s = (std::stringstream() << "foo").str();
Run Code Online (Sandbox Code Playgroud)

这不应该编译,因为std::stringstream::operator<<()它被继承std::ostream并返回一个没有成员的std::ostream&对象。str()

看来主要的编译器现在接受了这些代码,而他们过去并不接受。发生了什么标准变化来使这个编译?

我用GCCClangMSVC做了一些测试,我可以找到发生更改的版本:

编译器 拒绝直到(版本) 接受来自(版本)
海湾合作委员会 11.1 11.2
12.0.1 13.0.0
MSVC v19.14 v19.15

您可以在这里找到测试

c++ language-lawyer

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

主要问题是将平截头体从相机空间转换为光空间以进行阴影贴图

我正在尝试在我的OpenGL/C++渲染器中实现级联阴影贴图.当从任意数字构建正交矩阵并保持在场景的原点时,我已经成功地实现了定向阴影贴图.从我能看到的一切,我遇到的问题是根据视锥体的切片决定正交矩阵的界限.

我找到了两种计算方法,两者都是相关的; 第一种方法使用当前切片的近/远平面创建投影矩阵,然后将其反转.然后我在NDC空间中取一个立方体的角(每个轴的范围从[-1:+1]),将它乘以反转投影矩阵,倒置视图矩阵,然后是光空间矩阵; 然后将整个事物划分为角落的'w'.

vec4 corners[8] =
    {
        // Near plane
        { 1, 1, 1, 1 },
        { -1, 1, 1, 1 },
        { 1, -1, 1, 1 },
        { -1, -1, 1, 1 },
        // Far plane
        { 1, 1, -1, 1 },
        { -1, 1, -1, 1 },
        { 1, -1, -1, 1 },
        { -1, -1, -1, 1 }
    };

    // Create a projection matrix for this cascade.
    // This will transform the corner from camera space …
Run Code Online (Sandbox Code Playgroud)

c++ opengl matrix shadow

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

设置 QMenu::indicator:exclusive:checked 样式表会导致未选中的项目出现不良行为

我正在尝试设计 aQMenuBar及其子菜单(QMenu对象)的样式。

一切工作正常,直到我尝试设置自定义选中图标。

我有一个子菜单,其中包含两个独占且可检查的QAction。我已将两者添加到 a 中QActionGroup以使它们具有排他性(就像单选按钮一样)。

当我应用样式表而不尝试设置自定义选中图标时,我获得以下结果:

在此输入图像描述

到目前为止,一切正常。但我发现默认的选中图标很丑,我想更改它。
为此,我在样式表中添加了以下描述:

QMenu::indicator:exclusive:checked
{
    image: url(:/images/checked.png);
}
Run Code Online (Sandbox Code Playgroud)

当我应用它时,我现在得到以下结果:

在此输入图像描述

正如您所看到的,未选中的项目指示器沉入背景中(查看“系统主题”项目)。我尝试删除边框,设置一个空(或非空)未经检查的图像(:未经检查的伪状态),...没有任何效果。
我不知道这是否是 Qt 中的一个错误,但如果有人知道如何摆脱这个问题,我将非常感激,我对这个问题几乎发疯了。


编辑:

我已经进行了几次额外的测试,这似乎是一个错误。我在 Qt bug 跟踪器中报告了它。你可以在这里找到它。

我在错误报告附件中提供了最小且完整的示例,如果您想重现该错误,请随时下载它。

qt

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

具有单个互斥体的 std::scoped_lock 行为

语境:

我知道std::lock_guard自从std::scoped_lock.

我也知道这std::scoped_lock是首选,因为它可以处理多个互斥体,并以与之前相同的方式使用死锁避免算法std::lock

我对我们只有一个互斥体的情况感兴趣,因此我们不需要关心避免死锁。

我从这个答案中读到:

您可以考虑std::lock_guard弃用。的单参数情况std::scoped_lock可以作为专业化来实现,这样您就不必担心可能的性能问题。

问题:

我想知道这句话有多少是真实的。

我的意思是,是否(按照标准)保证使用单个互斥锁std::scoped_lock进行专门化,以便消除由于死锁避免处理而产生的任何不必要的开销?


我的想法:

经过对这个问题的一些调查,我从cppreference中发现了以下句子:

如果给出多个互斥体,则使用死锁避免算法,就像 一样std::lock

这可以让我们推断出这样的事情不会发生,否则(即,如果只给出一个互斥锁)。
但再次强调,这只是一个假设。

从这个c++ 草案中,我没有看到任何关于这种专业化的明确提及。
我得到的唯一一句话是:

sizeof...(MutexTypes)是 时1,提供的Mutex类型应满足Cpp17BasicLockable要求。否则,每种互斥体类型都应满足Cpp17Lockable要求。

(强调我的)

我知道BasicLockable要求要求存在满足此处定义的条件的lock()函数。 另一方面,Lockable需求假定了BasicLockable需求,并添加了满足此处定义的条件的函数。unlock()
try_lock()

我知道try_lock()需要该函数才能运行std::lock.

草稿摘录中的说明,try_lock()如果我们只向 提供一个互斥体,则不需要该函数 …

c++ mutex language-lawyer scoped-lock c++17

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

如何以安全且便携的方式为随机数生成器提供种子?

背景:

开始,建议使用 astd::random_device而不是 time 来为随机数生成器提供种子。如果我们看一下相关文档,我们可以读到:

std::random_device如果非确定性源(例如硬件设备)对于实现不可用,则可以根据实现定义的伪随机数引擎来实现。在这种情况下,每个std::random_device对象都可以生成相同的数字序列

强调我的

现在让我们考虑以下示例:

int main()
{
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_int_distribution distr(0, 9);

    // Print a sequence of 10 uniformly distributed random integers
    for(std::size_t i = 0; i < 10; ++i)
        std::cout << distr(gen) << ' ';

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

如果系统/平台不提供非确定性源,则该程序可能/将始终为每次运行生成相同的数字序列(实际上在我的平台上就是这种情况)。

在这种情况下,std::random_device比用当前时间播种随机数生成器要糟糕得多:

std::mt199937 gen(std::chrono::high_resolution_clock::now().time_since_epoch().count()); // time seed
Run Code Online (Sandbox Code Playgroud)

问题:

我担心的是,如果有人想编写一个依赖于一些随机生成的数字的程序,并且需要:

  1. 便于携带
  2. 保证非确定性随机性

那么std::random_device就不会是一个合适的人选。
另一方面,始终使用时间种子将是一个非常令人沮丧的“解决方案”,因为如果给定平台具有可用的非确定性源,std::random_device那么就会“更安全”。

问题:

我的问题分为两部分: …

c++ language-lawyer random-seed

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

std :: unique_ptr构造函数的行为

首先,我知道我们应该使用std::make_unique()而不是调用std::unique_ptr构造函数,而且我知道为什么。

但是我正在查看的文档,std::unique_ptr以打发时间并提高我的知识,发现了以下有关构造函数用法的示例

// unique_ptr constructor example
#include <iostream>
#include <memory>

int main () {
  std::default_delete<int> d;
  std::unique_ptr<int> u1;
  std::unique_ptr<int> u2 (nullptr);
  std::unique_ptr<int> u3 (new int);
  std::unique_ptr<int> u4 (new int, d);
  std::unique_ptr<int> u5 (new int, std::default_delete<int>());
  std::unique_ptr<int> u6 (std::move(u5));
  std::unique_ptr<int> u7 (std::move(u6));
  std::unique_ptr<int> u8 (std::auto_ptr<int>(new int));

  std::cout << "u1: " << (u1?"not null":"null") << '\n';
  std::cout << "u2: " << (u2?"not null":"null") << '\n';
  std::cout << "u3: " << (u3?"not null":"null") …
Run Code Online (Sandbox Code Playgroud)

c++ smart-pointers move-semantics

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

placement-new 到同一个类型中还需要手动调用析构函数吗?

语境

我正在尝试掌握新的放置机制,因为我从未使用过它。出于纯粹的好奇心,我试图了解如何正确使用它。

对于这个问题,我们将考虑以下代码库来进行说明:

struct Pack
{
    int a, b, c, d;
    Pack() = default;
    Pack(int w, int x, int y, int z) : a(w), b(x), c(y), d(z)
    {}
    ~Pack()
    {
        std::cout << "Destroyed\n";
    }
};

std::ostream & operator<<(std::ostream & os, const Pack & p)
{
    os << '[' << p.a << ", " << p.b << ", " << p.c << ", " << p.d << ']';
    return os;
}
Run Code Online (Sandbox Code Playgroud)

基本上它只是定义了一个保存一些数据的结构(示例中为 4 个整数),我重载了operator<<()来简化测试部分的代码。

我知道,当使用placement-new时,必须手动调用对象的析构函数,因为我们不能使用它,delete因为我们只想销毁该对象(而不是释放内存,因为它已经分配了)。

示例(A) …

c++ destructor placement-new

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

从输入参数具体用例推导的尾随返回类型

我已经看到了使用尾随返回类型的总是给定的原因之一是当我们想从输入参数中推断出返回类型时。
我知道还有其他原因,但我将重点放在这个问题上。

给定的示例之一是:

template <typename T>
auto func(const T & t) -> decltype(std::cout << t)
{
    return std::cout << t;
}
Run Code Online (Sandbox Code Playgroud)

但是我无法弄清楚这一点的具体用例。

我的意思是,编写函数时我们总是知道函数的返回类型,当确实需要并且无法避免从参数推导返回类型时,我找不到任何具体示例。

我们总是可以(如果我没有记错的话)通过直接指定返回类型而不用任何推导来重写函数的原型,这在我看来使它更加简洁明了。

上面的示例可以重写为:

template <typename T>
std::ostream& func(const T & t)
{
    return std::cout << t;
}
Run Code Online (Sandbox Code Playgroud)

在我看来,这比尾随返回类型版本更冗长,更易读。

我想念什么?

c++ trailing-return-type

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

Windows 10 上已安装应用程序的列表

我正在尝试以编程方式列出我的 win10 系统上所有已安装的应用程序。
基本上,我试图获取当您在资源管理器窗口中键入“shell:appsFolder”时可以看到的列表。

这是我使用的代码:

HRESULT hr;
IShellFolder *psParent= nullptr, *psApps= nullptr;
LPITEMIDLIST pidlSystem = NULL;
hr = SHGetFolderLocation(NULL, CSIDL_SYSTEM, NULL, NULL, &pidlSystem); // get root pidl which is needed to get the parrent of our app folder
LPITEMIDLIST pidlApps= NULL;

if (!SUCCEEDED(hr= SHGetKnownFolderItem(FOLDERID_AppsFolder, KF_FLAG_DEFAULT, NULL, IID_IShellItem , (void**)&pidlApps)))
    goto done;  // get pidl for apps folder

if (!SUCCEEDED(hr=SHBindToParent(pidlSystem, IID_IShellFolder, (void **) &psParent, (LPCITEMIDLIST*)&pidlApps)))
    goto done; // Get shell folder of parrent, which is needed to get shell folder of …
Run Code Online (Sandbox Code Playgroud)

c c++ windows winapi

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

为什么我无法创建唯一指针

尝试创建唯一指针时出现 c2664 错误

我确实编写了复制构造函数和赋值运算符,但仍然不断收到 2664 错误

class UndoCopyPaste : public UndoRedo
    {
    private:
        Container containerValue;
        bool valid;
    public:
        UndoCopyPaste() = default;
        UndoCopyPaste(Container* cont, std::string type);
        UndoCopyPaste(Container trans, Container* cont, std::string type);
        
    };
    
    class UndoRedo
    {
    private:
        std::string type;
    protected:
        Container* container;
    public:
        UndoRedo() = default;
        UndoRedo(Container* cont, std::string undoType);
    };
    
    std::unique_ptr<UndoCopyPaste> undoCopyPastePointer = std::make_unique<UndoCopyPaste>(new UndoCopyPaste()); // error C2664: 'UndoCopyPaste::UndoCopyPaste(UndoCopyPaste &&)': cannot convert argument 1 from '_Ty' to 'const UndoCopyPaste &'
Run Code Online (Sandbox Code Playgroud)

c++ c++11 c++14

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

自定义 strtoi 函数编译时问题

我正在尝试实现一个非常简单的strtoi功能。当动态创建传递的参数时,它工作正常(下面的情况 2)。但是,如果char[]在编译时分配的 char 是由which创建的,我会得到一个常量值,len因为std::strlen(ch)这会扰乱我的逻辑,我找不到解决方案。

 int strtoi(char* ch)
 {   
  int sum {0};
  int len = static_cast<int>(std::strlen(ch));
  int skipLast = static_cast<int>(static_cast<int>(ch[0]) == 45);

  //Integer Method
  for(int i = len - 1; i >= 0 + skipLast; i--)
  {
    if(static_cast<int>(ch[i]) < 48 || static_cast<int>(ch[i]) > 57)
      return 0;
    sum += (ch[i]-48) * std::pow(10,i-skipLast);
  }

   sum = skipLast == 1 ? -sum : sum;
   return sum;
 }

int main()
{
  char pos[3] {'1','2','3'};
  std::cout << strtoi(pos) …
Run Code Online (Sandbox Code Playgroud)

c++ compile-time-constant c++11

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

为什么删除复制构造函数后编译器不生成默认构造函数?

以下代码引发错误“没有匹配的构造函数来初始化‘A’”。为什么默认构造函数不能应用于它?我正在使用 C++ 17。

class A {
public:
    A(const A& a) = delete;
    static void test() {
        A a; // raises an error
    }
};
Run Code Online (Sandbox Code Playgroud)

我尝试显式添加默认构造函数,它有效。

c++ c++17

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

静态类中的向量

我想在静态类中有一个静态(常量)向量。向量不会填充新元素,它只会包含在 class configuration: 中定义的元素{1,2,3,4,5}

我怎样才能使向量debugLevels静态?

#include <ArduinoSTL.h>

class configuration {
  public:
  static std::vector<int> const debugLevels = {1,2,3,4,5}; // throws error: in-class initialization of static data member 'const std::vector<int> configuration::debugLevels' of incomplete type
};

void setup() {
  for(int i=0; i<configuration::debugLevels.size(); i++ {
    // do some stuff here...
  }
}

void loop() {
}
Run Code Online (Sandbox Code Playgroud)

c++ arduino

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