小编Yak*_*ont的帖子

C++ 17中有哪些新功能?

C++ 17现在功能齐全,因此不太可能经历大的变化.为C++ 17提出了数百个提案.

在C++ 17中,哪些特性被添加到C++中?

当使用支持"C++ 1z"的C++编译器时,当编译器更新到C++ 17时,哪些功能可用?

c++ standards c++-faq c++17

986
推荐指数
1
解决办法
21万
查看次数

传递可变数量的参数

假设我有一个带有可变数量参数的C函数:如何调用另一个函数,该函数需要从其内部获取可变数量的参数,并将所有参数传递到第一个函数中?

例:

void format_string(char *fmt, ...);

void debug_print(int dbg_lvl, char *fmt, ...) {
    format_string(fmt, /* how do I pass all the arguments from '...'? */);
    fprintf(stdout, fmt);
 }
Run Code Online (Sandbox Code Playgroud)

c variadic-functions

325
推荐指数
7
解决办法
17万
查看次数

对于带有数组的unique_ptr有什么用处吗?

std::unique_ptr 支持数组,例如:

std::unique_ptr<int[]> p(new int[10]);
Run Code Online (Sandbox Code Playgroud)

但它需要吗?可能使用std::vector或更方便std::array.

你觉得这个结构有用吗?

c++ smart-pointers c++11

219
推荐指数
12
解决办法
13万
查看次数

什么是C++ 20中的协同程序?

什么是中的协同程序?

它与"Parallelism2"或/和"Concurrency2"的不同之处(见下图)?

以下图片来自ISOCPP.

https://isocpp.org/files/img/wg21-timeline-2017-03.png

在此输入图像描述

c++ coroutine c++20

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

为什么即使我使用[[fallthrough]],GCC也会警告我一个漏洞?

在下面的代码中,我使用[[fallthrough]]C++ 1z中的标准属性来记录需要的漏洞:

#include <iostream>

int main() {
    switch (0) {
        case 0:
            std::cout << "a\n";
            [[fallthrough]]
        case 1:
            std::cout << "b\n";
            break;
    }
}
Run Code Online (Sandbox Code Playgroud)

使用GCC 7.1,代码编译时没有错误.但是,编译器仍然警告我一个问题:

warning: this statement may fall through [-Wimplicit-fallthrough=]
    std::cout << "a\n";
    ~~~~~~~~~~^~~~~~~~
Run Code Online (Sandbox Code Playgroud)

为什么?

c++ switch-statement fall-through c++17

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

奇怪的" - >*[]"表达式在cpp.react库的C++源代码中

这是我在cpp.react库的文档中找到的C++代码段:

auto in = D::MakeVar(0);
auto op1 = in ->* [] (int in)
{
    int result = in /* Costly operation #1 */;
    return result;
};
Run Code Online (Sandbox Code Playgroud)

我从未见过这种->* []符号.首先,我认为这只是一个错字,但我也在源代码中找到了这样一个表达式:

auto volume = (width,height,depth) ->* [] (int w, int h, int d) {
    return w * h * d;
};
Run Code Online (Sandbox Code Playgroud)

这是有效的C++ 11(或C++ 14)吗?这是什么意思?

c++ language-lawyer c++11 operator-arrow-star

55
推荐指数
3
解决办法
3787
查看次数

当我们可以编写自己的makefile时,为什么要使用像Autotools这样的构建工具?

最近,我将开发环境从Windows切换到了Linux.到目前为止,我只使用Visual Studio进行C++开发,因此许多概念,如makeAutotools,对我来说都是新的.我已经阅读了GNU makefile文档并且几乎了解了它.但我对Autotools感到困惑.

据我所知,makefile用于简化构建过程.

  1. 为什么我们需要像Autotools这样的工具来创建makefile?由于所有人都知道如何创建一个makefile,我没有真正使用Autotools.
  2. 标准是什么?我们需要使用这样的工具还是手写的makefile呢?

linux autotools gnu-make

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

为什么std :: move会阻止RVO?

在许多情况下,从函数返回局部时,RVO会启动.但是,我认为显式使用std::move至少会在RVO未发生时执行移动,但RVO仍然会在可能的情况下应用.但是,似乎情况并非如此.

#include "iostream"

class HeavyWeight
{
public:
    HeavyWeight()
    {
        std::cout << "ctor" << std::endl;
    }

    HeavyWeight(const HeavyWeight& other)
    {
        std::cout << "copy" << std::endl;
    }

    HeavyWeight(HeavyWeight&& other)
    {
        std::cout << "move" << std::endl;
    }
};

HeavyWeight MakeHeavy()
{
    HeavyWeight heavy;
    return heavy;
}

int main()
{
    auto heavy = MakeHeavy();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我用VC++ 11和GCC 4.71,debug和release(-O2)配置测试了这段代码.永远不会调用复制文件.移动ctor仅在调试配置中由VC++ 11调用.实际上,特别是这些编译器似乎都很好,但据我所知,RVO是可选的.

但是,如果我明确使用move:

HeavyWeight MakeHeavy()
{
    HeavyWeight heavy;
    return std::move(heavy);
}
Run Code Online (Sandbox Code Playgroud)

移动ctor总是被称为.因此,试图使其"安全"会使情况变得更糟.

我的问题是:
- 为什么要std::move预防RVO?
- 何时更好地"希望最好"并依赖RVO,何时应该明确使用 …

c++ move-semantics rvo c++11

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

不同的功能有不同的地址吗?

考虑这两个功能:

void foo() {}
void bar() {}
Run Code Online (Sandbox Code Playgroud)

是保证&foo != &bar吗?

同样的,

template<class T> void foo() { }
Run Code Online (Sandbox Code Playgroud)

是保证&foo<int> != &foo<double>吗?


我知道折叠函数定义有两个连接器.

MSVC积极地COMDAT折叠函数,因此具有相同实现的两个函数可以转换为一个函数.作为副作用,这两个函数共享相同的地址.我的印象是这是非法的,但我无法找到标准中的哪些内容是非法的.

Gold链接器还可以折叠功能,包括a safeall设置. safe意味着如果采用了一个功能地址,它就不会折叠,all即使采用了地址也会折叠.因此safe,如果函数具有不同的地址,则黄金的折叠表现为.

虽然折叠可能是意料之外的,并且存在依赖于具有不同地址的不同(相同实现)函数的代码(因此折叠可能是危险的),在当前的C++标准下它实际上是非法的吗?(此时为C++ 14)(自然如果safe折叠是合法的)

c++ function-pointers one-definition-rule language-lawyer comdat-folding

51
推荐指数
4
解决办法
2185
查看次数

std :: array初始化中的brace elision

假设有一个std::array要初始化的东西.如果使用双括号可以:

std::array<int, 2> x = {{0, 1}};
std::array<int, 2> x{{0, 1}};
Run Code Online (Sandbox Code Playgroud)

在良好的旧聚合初始化中使用单个括号也是可以的,因为括号省略将处理缺少的大括号:

std::array<int, 2> x = {0, 1};
Run Code Online (Sandbox Code Playgroud)

但是,使用单个括号的列表初始化是否可以?GCC接受它,Clang拒绝它"在使用直接列表初始化时不能省略关于子对象初始化的大括号".

std::array<int, 2> x{0, 1};
Run Code Online (Sandbox Code Playgroud)

提到括号内容的标准中唯一的部分是8.5.1/12,其中说:

使用赋值表达式初始化聚合成员时,将考虑所有隐式类型转换(第4节).如果赋值表达式可以初始化成员,则初始化成员.否则,如果成员本身是子集合,则假定使用大括号,并考虑赋值表达式初始化子集合的第一个成员.

8.5.1是关于聚合初始化的,所以应该意味着Clang是正确拒绝的,对吗?没那么快.8.5.4/3说:

列表初始化对象或类型T的引用定义如下:

[...]

- 否则,如果T是聚合,则执行聚合初始化(8.5.1).

我认为这意味着与聚合初始化完全相同的规则,包括括号elision,适用,意味着GCC是正确的接受.

我承认,措辞不是特别清楚.那么,哪个编译器正确处理第三个片段呢?括号省略是否在列表初始化中发生,或者不是?

c++ language-lawyer aggregate-initialization c++11 list-initialization

46
推荐指数
2
解决办法
5635
查看次数