小编dar*_*une的帖子

为什么在 C++20 中使用 `std::bind_front` 而不是 lambdas?

正如在一个类似措辞的问题中提到的(为什么在 c++14 中使用 bind over lambdas?)答案是 - 没有理由(并且还提到为什么使用 lambdas 会更好)。

我的问题是 - 如果在 C++14 中不再有理由使用绑定,为什么标准委员会认为有必要std::bind_front在 C++20 中添加?

它现在比 lambda 有什么新优势吗?

c++ lambda stdbind c++20 bind-front

48
推荐指数
2
解决办法
3121
查看次数

返回时不允许隐式转换

#include <optional>

bool f() {
  std::optional<int> opt;
  return opt;
}
Run Code Online (Sandbox Code Playgroud)

不编译: 'return': cannot convert from 'std::optional<int>' to 'bool'

咨询参考我本来想找到一个解释,但我读了它应该没问题。

每当在不接受该类型但接受其他类型 T2 的上下文中使用某种类型 T1 的表达式时,就会执行隐式转换;特别是:

  • 当调用以 T2 为参数声明的函数时,将表达式用作参数时;
  • 当表达式用作操作数时,运算符需要 T2;
  • 初始化 T2 类型的新对象时,包括返回 T2 的函数中的 return 语句;
  • 当表达式用于 switch 语句时(T2 是整型);
  • 当表达式用于 if 语句或循环时(T2 是 bool)。

c++ language-lawyer implicit-conversion c++17

25
推荐指数
2
解决办法
2127
查看次数

编译时间检查和运行时检查“同时”

假设我有以下简化程序:

链接到godbolt.org

#include <cassert>

struct Dimensions {

    Dimensions& operator=(int i) {
      assert(i != 0);
      return *this;
    }

};

int getDim();

int main() {
    Dimensions dims;
    dims = getDim();//ok, just use runtime assert
    dims = 0;//compile error wanted here
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在第一种情况(getDim)中,无法检查编译时,因此我们很高兴在运行时检查它。

但是在理论上看起来可行dims = 0;是否也可以通过某种方式检测到编译(对于第二种情况)?(甚至可能带有某种类型的重载或包装?)

c++ static-assert compile-time c++17

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

如何对参数包进行分组或配对折叠?

template<class Msg, class... Args>
std::wstring descf(Msg, Args&&... args) {
    std::wostringstream woss;

    owss << Msg << ". " << ... << " " << args << ": '" << args << "' ";//not legal at all

    //or

    owss << Msg << ". " << args[0] << ": '" << args[1] << "'  " << args[2] << ": '" << args[3] << "' "; //... pseudo code, and so on...
}
Run Code Online (Sandbox Code Playgroud)

我知道我可以只使用对列表或类似的东西,但我对如何做到这一点很感兴趣,同时保持函数的语法为:

const auto formatted = descf(L"message", "arg1", arg1, "arg2", arg2);
Run Code Online (Sandbox Code Playgroud)

c++ variadic-templates fold-expression c++17

14
推荐指数
3
解决办法
516
查看次数

基于无辜范围的循环无效

以下内容无法编译:

#include <iostream>

int main()
{
    int a{},b{},c{},d{};

    for (auto& s : {a, b, c, d}) {
        s = 1;
    }
    std::cout << a << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在Godbolt上尝试

编译器错误是: error: assignment of read-only reference 's'

现在,在我的实际情况中,列表由类中的成员变量组成。

现在,这不起作用,因为表达式变为initializer_list<int>实际上复制a,b,c和d的a,因此也不允许修改。

我的问题有两个:

不允许以这种方式编写基于范围的for循环背后有动机吗? 例如。也许会有一些特殊的情况来表达裸括号。

修复此类循环的语法整洁方法是什么?

最好遵循以下方式:

for (auto& s : something(a, b, c, d)) {
    s = 1;
}
Run Code Online (Sandbox Code Playgroud)

我认为指针间接寻址不是一个好的解决方案(即{&a, &b, &c, &d})-在取消迭代器时,任何解决方案都应直接给元素提供引用

c++ for-loop initializer-list c++17

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

升级后内环性能下降的原因是什么?

我有一个手动矩阵算法,它找到方阵的右下方的最大数量(因此在迭代时,某些部分被'跳过') - 存储为密集矩阵.在从的更新之后,似乎要慢得多 - 总体上放缓了50%.经过一些调查,这被定位到函数的内部循环中找到绝对最大值.查看输出,这似乎是由于在紧密循环中插入了一些额外的指令.以不同方式重新循环似乎可以解决或部分解决问题. 相比之下,似乎没有这个"问题".

简化示例(fabs并非总是需要重现):

#include <cmath>
#include <iostream>

int f_slow(double *A, size_t from, size_t w)
{
    double biga_absval = *A;
    size_t ir = 0,ic=0;
    for ( size_t j = 0; j < w; j++ ) {
      size_t n = j*w;
      for ( ; n < j*w+w; n++ ) {
        if ( fabs(A[n]) <= biga_absval ) {
          biga_absval = fabs( A[n] );
          ir   = j;
          ic …
Run Code Online (Sandbox Code Playgroud)

c++ optimization assembly compiler-optimization c++17

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

枚举像计算常数

实际上这个"问题"感觉非常简单.在做一些计算出的图标偏移时,我想出了以下方法:

namespace Icons {

  struct IconSet {
    constexpr IconSet(size_t base_offset) noexcept
      : base_offset_(base_offset), icon(base_offset * 3), iconSmall(icon + 1), iconBig(icon + 2) {
    }
    size_t icon;
    size_t iconSmall;
    size_t iconBig;

    size_t base_offset_;

    constexpr size_t next() const {
      return base_offset_ + 1;
    }
  };


  static constexpr IconSet flower = IconSet(0);
  static constexpr IconSet tree = IconSet(flower.next());
  static constexpr IconSet forest = IconSet(tree.next());
  static constexpr IconSet mountain = IconSet(forest.next());

 }
Run Code Online (Sandbox Code Playgroud)

现在可以编写一个Icons::tree.iconBig例子来获取该图标的计算偏移量.基本上,设计师可以更改图标 - 有时也可以添加/删除 - 但总是按惯例提供整个设置(正常,小和大).

如你所见,这种方法的问题是我必须做这个next()功能并重复使用它 - 正常的枚举不会有这个缺点. …

c++ constexpr c++17

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

constexpr映射要使用什么类型?

理想情况下,我想写:

constexpr std:map<std::string, std::string> my_map = 
  {{"key1", "val1"}, {"key2", "val2"}, };
Run Code Online (Sandbox Code Playgroud)

要么

constexpr std:unordered_map<std::string, std::string> my_map =
  {{"key1", "val1"}, {"key2", "val2"}, };
Run Code Online (Sandbox Code Playgroud)

但是都不可能(至少在当前语言是不可能的)

那还有什么选择呢?

例如,我可以做以下事情:

constexpr std::initializer_list< std::pair<const char*, const char *> > my_map = 
  {{"key1", "val1"}, {"key2", "val2"}, };
Run Code Online (Sandbox Code Playgroud)

然后在运行std::map时需要构造一个。我知道我也可以使用inline代替constexpr,但是那时我将无法在编译时使用(也许在开发的后期)。但是,这有点不令人满意(因为我不得不在运行时仅出于查找目的构造映射),我想知道:是否有更好的解决方案?

c++ stdmap constexpr c++17

10
推荐指数
0
解决办法
180
查看次数

std::remove_reference_t&lt;std::remove_cv_t&lt;T&gt;&gt; 顺序重要吗?

以下应用的顺序是否重要?

std::remove_reference_t<std::remove_cv_t<T>>
Run Code Online (Sandbox Code Playgroud)

或者

std::remove_cv_t<std::remove_reference_t<T>>
Run Code Online (Sandbox Code Playgroud)

在什么情况下,如果有的话,顺序重要吗?

c++ type-traits c++17

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

如何在 std::reduce 和 std::accumulate 之间进行选择?

std::accumulatestd::reduce做几乎相同的事情。

的总结std::reduce说明了一切:

similar to `std::accumulate`, except out of order 
Run Code Online (Sandbox Code Playgroud)

在许多情况下,这些函数应该产生相同的最终结果并展示相同的整体功能。很明显,如果您有一些非常重的负载计算等,您可以尝试std::reduce进行parrelization。IE。从鸟类的角度来看,这里的传统智慧是什么 - 除非明确优化,否则您是否应该始终坚持直率的 std::accumulate ?还是应该默认使用std::reduce

如果std::reduce(选择默认/未选择执行策略)总是至少与std::accumulate(保存一些指令)一样快,那么我认为只有在订单严格时才应使用累积。

c++ parallel-processing accumulate c++17

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