标签: c++20

Linux 包管理器将如何处理 C++20 模块?

现在是 2020 年,C++20 以及期待已久的 C++ 模块功能即将到来。但是在看了一些关于 CppCon 的演讲后,我发现 C++ 模块处于一个奇怪的地方,尤其是对于 Linux 包管理器(pacman、apt、emerge 等...)

据我所知,C++ 模块是

  1. 依赖编译器
    • 您不能在 Clang 中使用由 GCC 构建的模块
    • GCC 9.1 模块不适用于 GCC 9.2
  2. 您可以拥有同一模块的许多不同版本
    • 只要它们不导出到同一范围内
  3. 如果依赖项更新,您需要重建模块

我的问题是,在所有滚动发布发行版中,编译器一直在更新,用户可能有自己的编译器版本。目前可以只更新编译器或更新libstdc++. 但是对于模块,似乎建议libstdc++在编译器更新时必须更新。

当编译器更新时,包管理器将如何处理更新,例如 STL?我不认为为每个版本的编译器构建每个版本的 STL 模块是可行的。用户必须构建自己的 STL 模块也不是一个好主意。

c++ dependency-management package-management c++20 c++-modules

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

什么可以防止类中相邻成员重叠?

考虑以下三个方面struct

class blub {
    int i;
    char c;

    blub(const blub&) {}
};

class blob {
    char s;

    blob(const blob&) {}
};

struct bla {
    blub b0;
    blob b1;
};
Run Code Online (Sandbox Code Playgroud)

int4 字节的典型平台上,大小、对齐方式和总填充1如下:

  struct   size   alignment   padding  
 -------- ------ ----------- --------- 
  blub        8           4         3  
  blob        1           1         0  
  bla        12           4         6  

Run Code Online (Sandbox Code Playgroud)

blubblob成员的存储之间没有重叠,即使大小 1blob原则上可以“适合” blub.

C++20 引入了no_unique_address属性,它允许相邻的空成员共享相同的地址。它还明确允许使用一个成员的填充来存储另一个成员的上述场景。来自cppreference(强调我的):

指示此数据成员不需要具有与其类的所有其他非静态数据成员不同的地址。这意味着如果成员有一个空类型(例如无状态分配器),编译器可能会优化它以不占用空间,就像它是一个空基一样。如果该成员不为空,则其中的任何尾部填充也可以重新用于存储其他数据成员。

事实上,如果我们在 上使用这个属性blub b0,大小会bla …

c++ language-lawyer c++20

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

标准是否保证无捕获 lambda 为空?

我正在寻找一种方法来从模板函数中的其他 lambda 中识别空的(无捕获的)lambda。我目前正在使用 C++17,但我也对 C++20 的答案感到好奇。

我的代码如下所示:

template<typename T>
auto func(T lambda) {
    // The aguments of the lambdas are unknown

    if constexpr (/* is captureless */) {
        // do stuff
    }
}
Run Code Online (Sandbox Code Playgroud)

C++ 标准(17 或 20)是否保证可转换为函数指针的无捕获 lambda 也会使std::is_emptyyield 为真?

以这段代码为例:

auto a = []{}; // captureless
auto b = [c = 'z']{}; // has captures

static_assert(sizeof(a) == sizeof(b)); // Both are the same size
static_assert(!std::is_empty_v<decltype(b)>); // It has a `c` member
static_assert(std::is_empty_v<decltype(a)>); // Passes. It is guaranteed? …
Run Code Online (Sandbox Code Playgroud)

c++ lambda c++17 c++20

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

如何在cmake项目中使用c++20

我想使用 c++20 中可用的头文件。

我正在使用最新版本的 cmake。

我的 CMakeFiles 看起来像

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_BUILD_TYPE debug)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++20")
Run Code Online (Sandbox Code Playgroud)

我使用 clang 9 作为我的编译器。

但是,在包含以下内容时出现以下错误:

fatal error: 'format' file not found
#include <format>
Run Code Online (Sandbox Code Playgroud)

我也使用了标志-std=c++2a,但没有效果。简而言之,我觉得我在这里错过了一些重要的东西。我对 cmake 有点陌生,有什么帮助吗?

c++ format cmake c++20

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

如果可用,是否可以使用 std::endian ,否则做其他事情?

从 C++20 开始,我们可以有:

constexpr bool is_little_endian = std::endian::native == std::endian::little;
Run Code Online (Sandbox Code Playgroud)

如果可用,我希望有执行此操作的代码,否则执行运行时检测。这可能吗?

也许代码看起来像:

template<bool b = std_endian_exists_v> constexpr bool is_little_endian;
template<> constexpr bool is_little_endian<true> = std::endian::native == std::endian::little;
template<> constexpr bool is_little_endian<false> = runtime_detection();
Run Code Online (Sandbox Code Playgroud)

我知道__cplusplus通过预处理器进行测试是可能的,但是 C++20 中的编译器阶段在各个阶段都支持,因此这在任一方向都不是可靠的指标。

c++ endianness constexpr c++20

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

使用 GCC 10 泄漏的简单协程

考虑以下简单的协程,它跟踪其构建和销毁:

#include <coroutine>
#include <iostream>

struct simple {
  static inline int x = 0;
  int id = 0;
  simple() : id{ x++ } { std::cout << id << " constructed\n"; }
  simple(simple&&) : id{ x++ } { std::cout << id << " move constructed\n"; }
  ~simple() { std::cout << id << " destructed\n"; }

  struct promise_type {
    simple get_return_object() { return {}; }
    void return_void() {}
    void unhandled_exception() { std::terminate(); }
    auto initial_suspend() noexcept { return std::suspend_never{}; }
    auto final_suspend() …
Run Code Online (Sandbox Code Playgroud)

c++ gcc c++20

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

授予模板类专业化的构造函数/析构函数友好 - 在 C++17 下工作,但在 C++20 下失败

我发现了一种情况,代码在 C++17 下编译成功,但在 C++20 下编译失败。
这阻止了我们将现有的代码设计升级到更新的标准。
为什么这不能在 C++20 下编译?这似乎是对向后兼容性的奇怪破坏。

当我尝试为模板类专业化的构造函数/析构函数授予友好关系时会发生错误。

我正在使用带有 Ninja 的 MSVC 进行编译。
在 C++17 下编译成功。
在 C++20 下,我收到以下错误:

error C2838: '{ctor}': illegal qualified name in member declaration
error C2838: '{dtor}': illegal qualified name in member declaration
Run Code Online (Sandbox Code Playgroud)

这是在 C++20 下导致错误但在 C++17 下编译成功的代码的简化复制:

template<typename T, int V> class B {};

// specialization of class B
template<typename T> class B<T, 0> {
private:
    T _t;   // private data member
public:
    constexpr inline B(T* p, int i) noexcept;   // B constructor …
Run Code Online (Sandbox Code Playgroud)

c++ friend friend-function language-lawyer c++20

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

为什么 C++20 的要求表达式的行为不符合预期?

#include <type_traits>

template<typename T>
struct IsComplete final
    : std::bool_constant<requires{sizeof(T);}>
{};

int main()
{
    struct A;
    static_assert(!IsComplete<A>::value); // ok

    struct A{};
    static_assert(IsComplete<A>::value);  // error
}
Run Code Online (Sandbox Code Playgroud)

我预计第二个static_assert应该是真的,因为 A 现在是一个完整的类型。

为什么 C++20 的要求表达式的行为不符合预期?

c++ templates sfinae type-traits c++20

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

如何定义任意 std::vector 满足的概念?

我想要一个concept需要任意向量作为返回类型:

template<typename T>
concept HasVector = requires (T t) {
    { T.vec() } -> std::same_as<std::vector<int>>; //works
    { T.vec() } -> std::same_as<std::vector<foo>>; //want to put something arbitrary in here
}
Run Code Online (Sandbox Code Playgroud)

这样我们就会有如下内容:

class A {
std::vector<int> vec() { /* ... */}
}

class B {
std::vector<double> vec() { /* ... */}
}

static_assert(HasVector<A>);
static_assert(HasVector<B>);
Run Code Online (Sandbox Code Playgroud)

此外,要求一个向量作为返回类型会更好,其值类型满足其他一些概念,即


template<typename T>
concept Arithmetic = // as in the standard

template<typename T>
concept HasArithmeticVector = requires (T t ) {
    { T. vec() } -> …
Run Code Online (Sandbox Code Playgroud)

c++ templates vector c++-concepts c++20

12
推荐指数
2
解决办法
1117
查看次数

使用函数作为回调时,有没有办法避免存储开销?

鉴于以下设置:

// ***** Library Code *****
#include <concepts>

template <std::invocable CbT>
struct delegated {
  explicit constexpr delegated(CbT cb) : cb_(std::move(cb)) {}

 private:
  [[no_unique_address]] CbT cb_;
};

// ***** User Code *****
#include <iostream>

namespace {
  inline constexpr void func() {}
}

struct MyFunc {
  constexpr void operator()() const {}
};


int main() {
    void (*func_ptr)() = func;

    auto from_func = delegated{func};
    auto from_func_ptr = delegated{func_ptr};
    auto from_lambda = delegated{[](){}};
    auto from_functor = delegated{MyFunc{}};

    std::cout << "func: " << sizeof(from_func) << …
Run Code Online (Sandbox Code Playgroud)

c++ c++20

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