标签: c++17

为什么没有将产量添加到C++ 0x?

我在许多Python程序中都使用了yield,在很多情况下它确实清除了代码.我在博客上写了这篇文章,这是我网站的热门网页之一.

C#还提供了收益 - 它通过调用者端的状态保持来实现,通过自动生成的类来完成,该类保持状态,函数的局部变量等.

我目前正在阅读有关C++ 0x及其添加的内容; 在阅读有关C++ 0x中lambda的实现时,我发现它也是通过自动生成的类完成的,配备了存储lambda代码的operator().我心中形成了一个自然的问题:他们是为lambdas做过的,他们为什么不考虑支持"收益"呢?

当然,他们可以看到合作例程的价值......所以我只能猜测他们认为基于宏的实现(例如Simon Tatham的)是一个充分的替代品.然而,它们不是出于多种原因:被调用者保持状态,非重入状态,基于宏观(仅此一点是足够的理由)等.

编辑: yield不依赖于垃圾收集,线程或光纤.您可以阅读Simon的文章,看看我在谈论编译器进行简单的转换,例如:

int fibonacci() {
    int a = 0, b = 1;
    while (true) {
        yield a;
        int c = a + b;
        a = b;
        b = c;
    }
}
Run Code Online (Sandbox Code Playgroud)

成:

struct GeneratedFibonacci {
    int state;
    int a, b;

    GeneratedFibonacci() : state (0), a (0), b (1) {}

    int operator()() {
        switch (state) {
        case 0:
            state = 1;
            while (true) { …
Run Code Online (Sandbox Code Playgroud)

c++ yield c++11 c++17

30
推荐指数
4
解决办法
9139
查看次数

使用STL并行算法的用户有哪些限制?

在杰克逊维尔会议上,有效采用Parallelism TS规范的提议P0024r2被接受到C++ 17(草案)中.该提议为许多算法添加了重载,这些算法采用执行策略参数来指示应该考虑哪种并行性.在(20.19.2 [执行])中已经定义了三个执行策略:<execution>

  • std::execution::sequenced_policy(20.19.4 [execpol.seq])带有一个constexpr对象std::execution::seq(20.19.7 [parallel.execpol.objects])来表示顺序执行,类似于在没有执行策略的情况下调用算法.
  • std::execution::parallel_policy(20.19.5 [execpol.par])带有一个constexpr对象std::execution::par(20.19.7 [parallel.execpol.objects]),表示可能使用多个线程执行算法.
  • std::execution::parallel_unsequenced_policy(20.19.6 [execpol.vec])带有一个constexpr对象std::execution::par_unseq(20.19.7 [parallel.execpol.objects]),表示可能使用向量执行和/或多个线程执行算法.

STL算法通常将用户定义的对象(迭代器,函数对象)作为参数.用户定义的对象有哪些限制,使它们可以使用标准执行策略与并行算法一起使用?

例如,当使用如下例中的算法时,对FwdItand 的含义是Predicate什么?

template <typename FwdIt, typename Predicate>
FwdIt call_remove_if(FwdIt begin, FwdIt end, Predicate predicate) {
    return std::remove_if(std::execution::par, begin, end, predicate);
}
Run Code Online (Sandbox Code Playgroud)

c++ stl c++17

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

如何使用CMake在VS2017中启用/ std:c ++ 17

我正在尝试/std:c++17使用CMake 将编译器标志添加到VS2017.到目前为止,我正在使用"现代"的跨平台方式:

set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF) # -std=c++11 instead of -std=gnu++11
set(MY_CXX_COMPILE_FEATURES cxx_generic_lambdas cxx_range_for cxx_strong_enums)

add_library(mylib INTERFACE)
target_compile_features(mylib INTERFACE ${MY_CXX_COMPILE_FEATURES})
Run Code Online (Sandbox Code Playgroud)

这增加/std:c++14了VS2017(无论如何可能是默认值?).但是我无法将其切换到C++ 17(即添加它/std:c++17).如果我只是手动添加它,我会收到不太好的警告,因为两个标志都存在:

1>cl : Command line warning D9025: overriding '/std:c++14' with '/std:c++17'

我已经尝试set(CMAKE_CXX_STANDARD 17)但它没有效果,事实上CMake文档提到CMAKE_CXX_STANDARD对VS无影响.

至于添加C++ 17功能target_compile_features,它似乎还没有(甚至在CMake-3.9.0-rc5中),即使有,我特别只使用std::optionalC++ 17 ,并没有target_compile_features像图书馆功能的标志std::optional.

所以我的问题是,使用CMake做到这一点的最好(或最不丑陋)的方法是什么?在某种程度上它也适用于gcc和clang?我很高兴使用最近的CMake版本(3.8或3.9).我更喜欢它是"好"而不是手动循环通过CXX_COMPILE_FLAGS并删除字符串"/ std:c ++ 14"或类似的一些黑客.

(编辑:它也可以是VS /std:c++latest开关 - 以可能的为准.两者都可以用于此目的.)

c++ cmake c++17 visual-studio-2017

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

如何制作更安全的C++变体访问者,类似于switch语句?

许多人使用C++ 17/boost变体的模式看起来与switch语句非常相似.例如:( 来自cppreference.com的片段)

std::variant<int, long, double, std::string> v = ...;

std::visit(overloaded {
    [](auto arg) { std::cout << arg << ' '; },
    [](double arg) { std::cout << std::fixed << arg << ' '; },
    [](const std::string& arg) { std::cout << std::quoted(arg) << ' '; },
}, v);
Run Code Online (Sandbox Code Playgroud)

问题是当您在访问者中输入错误的类型或更改变体签名时,但忘记更改访问者.您将获得错误的lambda,通常是默认的lambda,而不是获得编译错误,或者您可能会得到一个您没有计划的隐式转换.例如:

v = 2.2;
std::visit(overloaded {
    [](auto arg) { std::cout << arg << ' '; },
    [](float arg) { std::cout << std::fixed << arg << ' '; } // oops, this won't …
Run Code Online (Sandbox Code Playgroud)

c++ visitor variant switch-statement c++17

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

具有引用成员的结构是否具有唯一的对象表示?

这个答案提出了以下问题。

假设我们有一个简单的

struct S {
    int& i;
}
Run Code Online (Sandbox Code Playgroud)

内部(至少在 GCC 和 Clang 中)S只包含一个指向 an 的指针int,并且

static_assert(sizeof(int*) == 8);
static_assert(sizeof(S)    == 8);
Run Code Online (Sandbox Code Playgroud)

是否S有唯一的对象表示?GCC 和 Clang 不同意 *:

static_assert( std::has_unique_object_representations_v<int*>);
static_assert(!std::has_unique_object_representations_v<S>);    // GCC
static_assert( std::has_unique_object_representations_v<S>);    // Clang
Run Code Online (Sandbox Code Playgroud)

哪个编译器就在这里,为什么?

* idclev 463035818指出 GCC 和 Clang 之间存在分歧

c++ language-lawyer c++17

30
推荐指数
3
解决办法
829
查看次数

如果 constexpr 失败,为什么 C++17 的这种用法会失败?

我正在尝试使用 C++17if constexpr进行条件编译,但它的行为并不符合我的预期。

比如下面的代码,C++还是编译宏定义的代码X2

#include <map>
#include <string>
#include <iostream>
#include <type_traits>

#define X1 pp("x")
#define X2 pp("x", "x")

void pp(const std::string str)
{
   std::cout << str << std::endl;
}

int main()
{
   std::map<std::string, int> map;

   if constexpr (std::is_null_pointer_v<decltype(map)>)
      X2;
   else
      X1;
}
Run Code Online (Sandbox Code Playgroud)

并吐出此错误消息:

#include <map>
#include <string>
#include <iostream>
#include <type_traits>

#define X1 pp("x")
#define X2 pp("x", "x")

void pp(const std::string str)
{
   std::cout << str << std::endl;
}

int main()
{
   std::map<std::string, int> map; …
Run Code Online (Sandbox Code Playgroud)

c++ templates if-statement constexpr c++17

30
推荐指数
3
解决办法
3339
查看次数

新的std :: map :: erase()签名C++ 17

根据这个答案,iterator必须可以隐含地转换为const_iterator.insert_or_assign()既然如此,正如我们可以看到的那样,为什么在C++ 17中添加了新的签名std::map::erase()

在C++ 11中,我们有 iterator erase( const_iterator pos );

在C++ 17中,我们现在有了 iterator erase( iterator pos );

是不是C++ 11签名足以接收iteratorconst_iterator

c++ iterator const-iterator c++11 c++17

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

有没有办法通过使用十进制ASCII代码的自动类型推导来获取char?

例如,'a'具有ASCII码97,我们可以使用

char ch = 'a';
Run Code Online (Sandbox Code Playgroud)

要么

char ch = 97;
Run Code Online (Sandbox Code Playgroud)

auto我们可以写

auto ch = 'a';
Run Code Online (Sandbox Code Playgroud)

对于第一种情况,但如何在演绎期间通过数字ascii代码获取char变量?

这对我不起作用:

auto ch = '\97';
Run Code Online (Sandbox Code Playgroud)

c++ c++14 c++17

29
推荐指数
3
解决办法
1417
查看次数

什么决定了 constexpr 函数是否是常量表达式?

(据我所知,使用的编译器是带有 c++17 的 gcc(在 Visual Studio 中很难找到))

#include <iostream>

using namespace std;

void increment( int& v )
{
    ++v;
}

int constexpr f()
{
    int v = 0;
    increment( v );
    return v;
}

int main( )
{
    cout << f( ) << '\n';
}
Run Code Online (Sandbox Code Playgroud)

上面的代码给出了编译错误:

constexpr 函数 'f' 不能产生常量表达式。

据我了解,这是因为该函数increment不是 constexpr。让我困惑的是以下代码编译得很好:

#include <iostream>

using namespace std;

void increment( int& v )
{
    ++v;
}

int constexpr f()
{
    int v = 0;
    for( int i = 0; …
Run Code Online (Sandbox Code Playgroud)

c++ constexpr c++17

29
推荐指数
2
解决办法
1376
查看次数

在编译时使整数序列唯一

假设我有:

template<int... N>
class seq
{
};

template<int... N>
struct uniq{
    using type = seq<N...>;
};
Run Code Online (Sandbox Code Playgroud)

我需要以某种方式使序列唯一,以便

std::is_same_v<uniq<1,2,2,2,3,3,3>::type, seq<1, 2, 3>>; 
Run Code Online (Sandbox Code Playgroud)

最终是真的。换句话说,使序列唯一,然后创建一个 seq。
有没有办法在编译时实现这一点?

c++ templates template-meta-programming c++17

29
推荐指数
2
解决办法
1461
查看次数