小编Mik*_*ail的帖子

c ++中的参考解释

请考虑以下代码:

#include <iostream>

template<typename T>
void inc1(T&& x)
{
    T y = x;
    ++y;
}

template<typename T>
void inc2(T& x)
{
    T y = x;
    ++y;
}

int main()
{
    int a = 10;
    inc1(a); // a is now 11

    int b = 10;
    inc2(b); // b remains 10
}
Run Code Online (Sandbox Code Playgroud)

替换后我们有

void inc1(int& x)
{
    int& y = x; // reference to x
    ++y; // increments x
}

void inc2(int& x)
{
    int y = x; // copy of x …
Run Code Online (Sandbox Code Playgroud)

c++ c++11

16
推荐指数
2
解决办法
508
查看次数

断言代码不编译

简而言之:

如何编写测试,检查我的类是不可复制的还是可复制的,但只能移动并可移动分配?

一般来说:

如何编写测试,确保特定代码编译?像这样:

// Movable, but non-copyable class
struct A
{
  A(const A&) = delete;
  A(A&&) {}
};

void DoCopy()
{
  A a1;
  A a2 = a1;
}

void DoMove()
{
  A a1;
  A a2 = std::move(a1);
}

void main()
{
  // How to define these checks?
  if (COMPILES(DoMove)) std::cout << "Passed" << std::endl;
  if (DOES_NOT_COMPILE(DoCopy)) std::cout << "Passed" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

我想与SFINAE有关,但有一些现成的解决方案,也许是在提升?

c++ boost compiler-errors sfinae c++11

16
推荐指数
3
解决办法
2511
查看次数

为什么约束函数允许未定义的行为?

C ++中的常量表达式具有非常整洁的特性:它们的求值不能具有未定义的行为(7.7.4.7):

表达式e是核心常量表达式,除非按照抽象机([intro.execution])的规则对e求值,将求出以下值之一:

  • ...

  • 一种操作,其操作将具有本文档的[引言] [cpp]中指定的不确定的行为[注意:例如,包括带符号整数溢出([expr.prop]),某些指针算术([expr.add],除以零或某些移位操作-尾注];

尝试将13!in 的值存储在constexpr int确实产生一个不错的编译错误

constexpr int f(int n) 
{
    int r = n--;
    for (; n > 1; --n) r *= n;
    return r;
}

int main() 
{
    constexpr int x = f(13);
    return x;
}
Run Code Online (Sandbox Code Playgroud)

输出:

9:19: error: constexpr variable 'x' must be initialized by a constant expression
    constexpr int x = f(13);
                  ^   ~~~~~
4:26: note: value 3113510400 is outside the range of representable values …
Run Code Online (Sandbox Code Playgroud)

c++ undefined-behavior c++20 consteval

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

从Windows隐藏显示器,仅从我的应用程序使用它

我需要使用显示器作为我的特殊应用程序的"私人"设备,我想将它用作一种类型的手电筒并在其上全屏绘制特殊图案.我不希望OS(Windows 7)将此监视器识别为常用监视器.即用户不应该将鼠标移动到该监视器,或更改其分辨率,或在其上运行屏幕保护程序或其他任何内容.但我希望能够从我的应用程序中与它进行交互.使用HDMI电缆将显示器插入视频卡(最可能是nVidia).

最简单的方法是什么?所有解决方案都受到赞赏,包括购买额外的适配器或简单的视频卡,或任何其他特殊设备.我现在想象的唯一解决方案是将显示器插入另一台计算机,在该计算机上运行一个守护程序,通过以太网或其他任何方式将其连接到我的计算机,从我的计算机与该守护程序进行通信.它很丑陋,需要额外的电脑.但我需要解决这个问题.

windows hardware multiple-monitors

14
推荐指数
2
解决办法
413
查看次数

C++中的安全指针解除引用

在我们的代码库中,我们有许多这样的结构:

auto* pObj = getObjectThatMayVeryRarelyBeNull();
if (!pObj) throw std::runtime_error("Ooops!");
// Use pObj->(...)
Run Code Online (Sandbox Code Playgroud)

在99.99%的情况下,不会触发此检查.我正在考虑以下解决方案:

auto& obj = deref_or_throw(getObjectThatMayVeryRarelyBeNull());
// Use obj.(...)
Run Code Online (Sandbox Code Playgroud)

deref_or_throw声明如下:

template<class T> T& deref_or_throw(T* p) {
  if (p == nullptr) { throw std::invalid_argument("Argument is null!"); }
  return *p;
}
Run Code Online (Sandbox Code Playgroud)

该代码更清晰,可以根据需要使用.

问题是:我是否重新发明轮子?在标准或提升中是否有一些相关的解决方案?或者你对解决方案有一些评论?

PS.相关问题(没有令人满意的答案):是否存在与NullPointerException相当的C++

c++ exception nullpointerexception dereference

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

可以“T t = {};” 和“T t{};” 产生不同的结果?

问题很简单。是否可以构造这样一个类型 T,对于它下面的两个变量声明会产生不同的结果?

T t1 = {};
T t2{};
Run Code Online (Sandbox Code Playgroud)

我已经研究 cppreference 和标准一个多小时了,我了解以下内容:

但是最后一个很棘手,因为“列表初始化的效果”是一个令人印象深刻的......列表。对于类,基本类型和聚合似乎归结为值初始化。但我不确定我没有错过任何东西。

也许您可以提供一个上下文,其中两个声明会产生不同的效果?

UPD:关于explicit构造函数的优秀答案!下一级:是否有可能两个语句都编译,但对编译/运行时有不同的影响?

c++ initialization language-lawyer

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

为什么对于左值,明确选择左值引用重载而不是转发引用重载?

看一下这两个重载的函数模板:

template <class T>
int foo(T& x) {  // #1
  return 1;
}
template <class T>
int foo(T&& x) {  // #2
  return 2;
}
Run Code Online (Sandbox Code Playgroud)

foo通过以下方式调用:

int i;
foo(i);  // calls #1
Run Code Online (Sandbox Code Playgroud)

并且明确选择了重载#1:https ://gcc.godbolt.org/z/zchK1zxMW

这似乎是一个正确的行为,但我无法理解为什么会发生(而且我实际上有代码,这不是我所期望的)。

过载分辨率

如果任何候选者是函数模板,则其特化是使用模板参数推导生成的,并且此类特化被视为与非模板函数一样,除非在决胜规则中另有指定。

好的,让我们生成专业化。对于#1来说,这很容易,它就变成了int foo(int& x)。对于 #2,适用特殊扣除规则,因为它是转发参考。i是一个左值,因此T被推导为int&T&&变为int& &&,在引用折叠后变为 just int&,产生结果int foo(int& x)。这与#1 完全相同!

所以我希望看到一个不明确的调用,但这并没有发生。谁能解释一下为什么吗?这里使用什么决定因素来选择最佳可行的功能?

另请参阅Slack 中的相关讨论,其中有一些想法。

c++ templates overloading forwarding-reference

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

根据转换后的值查找最小元素

以下是代码审查中发现的任务.我想根据特殊类型的比较谓词从集合中选择最小值.像这样:

struct Complex { ... };

float calcReduction(Complex elem);

Complex findMinValueWithPredicates(const std::vector<Complex>& values)
{
  auto it = std::min_element(values.begin(), values.end(), 
                             [](const Complex& a, const Complex& b) { 
                               return calcReduction(a) < calcReduction(b); 
                             });

  if (it == values.end()) throw std::runtime_error("");

  return *it;
}
Run Code Online (Sandbox Code Playgroud)

在这里,我找到了基于谓词的最小元素.此谓词计算两个值的减少,float然后比较这些浮点数.工作正常,看起来整洁.

你能看到问题吗?是的,对于一组N元素calcReduction()称为2N时间,而它只足以计算它N- 每个元素一次.

解决此问题的一种方法是编写显式计算:

Complex findMinValueExplicit(const std::vector<Complex>& values)
{
  float minReduction = std::numeric_limits<float>::max();
  Complex minValue;

  for (Complex value : values)
  {
    float reduction = calcReduction(value);
    if (reduction < …
Run Code Online (Sandbox Code Playgroud)

c++ algorithm min range-v3 c++17

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

为什么Sortable概念需要完全有序的值类型,而std :: sort只需要"小于"可比性?

关于概念N3701最新论文中,该sort算法有以下示例:

template<typename Cont>
  requires Sortable<Cont>()
void sort(Cont& cont)
Run Code Online (Sandbox Code Playgroud)

其中Sortable概念被定义为

template<typename T>
concept bool Sortable()
{
  return Permutable_container<T>() && Totally_ordered<Value_type<T>>();
}
Run Code Online (Sandbox Code Playgroud)

其中Totally_ordered,毫不奇怪,定义为

template<typename T>
constexpr bool Totally_ordered()
{
  return Weakly_ordered<T>() && Equality_comparable<T>();
}
Run Code Online (Sandbox Code Playgroud)

反过来Equality_comparable被定义为

template<typename T>
constexpr bool Equality_comparable()
{
  return requires(T a, T b) {
    {a == b} -> bool;
    {a != b} -> bool;
  };
}
Run Code Online (Sandbox Code Playgroud)

我没有找到定义Weakly_ordered,但我相信它应该是这样的(我是对的吗?)

template<typename T>
constexpr bool Weakly_ordered()
{
  return requires(T …
Run Code Online (Sandbox Code Playgroud)

c++ c++-concepts c++17

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

将const引用存储在类中的对象中

这听起来像一个基本问题,但我没有找到任何全面的答案,所以在这里.请考虑以下代码段:

struct A {
    const std::string& s;
    A(const std::string& s) : s(s) {}
};

int main() {
    A a("abc");
    std::cout << a.s << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

演示.

只要我明白,这就是UB.字符串文字"abc"绑定到const std::string&构造函数中,创建一个临时字符串对象.它也必须引用a.s,并且一旦a被构造就被销毁.也就是说,const引用不能链延长寿命延长.晃来晃去参考,热潮.在这个特殊情况下,我在ideone.com上看不到任何输出,但任何事情都可能发生(请记住速龙).

好的,这个很清楚.但是,如果这实际上是我们的意图呢:我们想要存储对象的const引用?对现有的,不是暂时的?这听起来像是一项非常自然的任务,但我只想出一个(几乎)自然的解决方案.接受构造函数的参数std::reference_wrapper而不是引用:

    A(std::reference_wrapper<const std::string> r) : s(r) {}
Run Code Online (Sandbox Code Playgroud)

既然std::reference_wrapper删除了临时的构造函数:

reference_wrapper( T&& x ) = delete;
Run Code Online (Sandbox Code Playgroud)

这个工作就像预期一样.但是,这并不是很优雅.我能想到的另一种方法是接受转发引用T&&并拒绝除const l-value字符串之外的所有内容std::enable_if.我认为这更不优雅.

还有其他方法吗?

UPD另一个问题:这是合法使用std::reference_wrapper,还是可能被认为过于具体?

c++ pass-by-reference c++11

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