小编Des*_*old的帖子

概念可能会取代 C++ 中的类型特征吗?

我已经知道这个概念是一个编译时谓词,它可以约束模板或auto.

我发现这些概念将返回 type 的纯右值bool,所以我可以打印它来测试自己。

我还阅读了这个特定问题Can概念(C++ 20)可以用作布尔值吗?以及澄清可用作布尔值的概念的答案。

[temp.names] (8) 一个concept-id 是一个simple-template-id,其中template-name 是一个concept-name。概念 ID 是 bool 类型的纯右值,并且不命名模板特化。如果指定的模板参数满足概念的规范化约束表达式 ([temp.constr.constr]),则概念 ID 评估为真,否则为假。

例如:

template <typename T>
concept meowable = requires (T obj) {
    { obj.meow() } -> std::same_as<T&>;
};

struct Dog {};
struct Cat { Cat& meow(); };
struct Wolf { Wolf& woof(); };
Run Code Online (Sandbox Code Playgroud)

应用:

std::cout << std::boolalpha;

std::cout << "Has meow?" << '\n'
          << "Dog:  " << meowable<Dog>  << '\n'
          << "Cat:  " << meowable<Cat>  << '\n' …
Run Code Online (Sandbox Code Playgroud)

c++ type-traits template-meta-programming c++-concepts c++20

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

为什么C++概念中没有前向声明?

当我尝试这个例子时:

template <typename T>
concept only_int = std::same_as<T, int>;

int add_ints(only_int auto&&... args) {
    return (std::forward<decltype(args)>(args) + ... + 0);
}
Run Code Online (Sandbox Code Playgroud)

它有效......但是当我只像这样声明它时:

template <typename T>
concept only_int;

...

// defined later on...
Run Code Online (Sandbox Code Playgroud)

它会抛出编译错误。

这是缺少的功能吗?还是打算就这样离开?

c++ forward-declaration c++-concepts c++20

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

如何在自定义容器中支持范围适配器?

我创建了一个名为的自定义容器goldbox,它仅包含算术类型,并且我还实现了begin成员end函数来迭代元素。

我的完整源代码:

#include <algorithm>
#include <vector>
#include <initializer_list>
#include <iostream>
#include <type_traits>
#include <ranges>

template <typename T>
concept Arithmetic = std::is_arithmetic_v<T>;

template <Arithmetic T = int>
class goldbox {
private:
    template <Arithmetic Base_t>
    struct Node {
        Base_t data;
        Node<Base_t>* prev;
        Node<Base_t>* next;
    };
    Node<T>* head;
    Node<T>* current_node;

    Node<T>*& __at_node(size_t index) {
        auto temp = head;
        size_t count {0};

        while (count < index) {
            temp = temp->next;
            count++;
        }
        current_node = temp;

        return current_node;
    } …
Run Code Online (Sandbox Code Playgroud)

c++ c++20 std-ranges

7
推荐指数
1
解决办法
993
查看次数

C++中的split_view和lazy_split_view有什么区别?

我已经阅读了最新的草案,其中lazy_split_view添加了内容。

但后来我发现它split_view改名为lazy_split_view,而且又split_view更新了。

libstdc++最近还通过使用GCC Trunk版本https://godbolt.org/z/9qG5T9n5h实现了这一点

我这里有一个简单的天真的程序,它显示了两个视图的用法,但我看不到它们的区别:

#include <iostream>
#include <ranges>

int main(){

    std::string str { "one two three  four" };

    for (auto word : str | std::views::split(' ')) {
        for (char ch : word)
            std::cout << ch;
        std::cout << '.';
    }

    std::cout << '\n';

    for (auto word : str | std::views::lazy_split(' ')) {
        for (char ch : word)
            std::cout << ch;
        std::cout << '.';
    }

}
Run Code Online (Sandbox Code Playgroud)

输出:

one.two.three..four.
one.two.three..four. …
Run Code Online (Sandbox Code Playgroud)

c++ std-ranges c++23

7
推荐指数
1
解决办法
2123
查看次数

如何使用 g++ 在 c++ 20 中使用模块?

我阅读了此链接https://gcc.gnu.org/wiki/cxx-modules并尝试从该网站复制以下示例。我已经知道这个编译器部分支持模块系统。(注:我用的是windows)

// hello.cc
module;
#include <iostream>
#include <string_view>
export module hello;
export void greeter(std::string_view const &name) {
  std::cout << "Hello " << name << "!\n";
}
Run Code Online (Sandbox Code Playgroud)
// main.cc
import hello;
int main() {
  greeter("world");
  return 0;
}
// Should print "Hello world!" 
Run Code Online (Sandbox Code Playgroud)

我目前有GCC 11.0.1快照,并尝试使用以下参数编译这些文件: g++ -std=gnu++2b -Wall -fmodules-ts hello.cc main.cc编译器给了我这些错误:

hello.cc:6:8: internal compiler error: in get_cxx_dialect_name, at cp/name-lookup.c:7027
    6 | export module hello;
      |        ^~~~~~
libbacktrace could not find executable to open
Please submit …
Run Code Online (Sandbox Code Playgroud)

c++ g++ c++20 c++-modules

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

C++23 中显式 *this 对象参数提供什么?

在C++23中,推导这一点最终被添加到标准中。

根据我从提案中读到的内容,它开辟了一种创建 mixins 的新方法,并且可以创建递归 lambda。

但是我很困惑,如果这个参数在不使用模板的情况下创建“副本”,因为没有引用,或者显式this参数是否有自己的值类别规则?

自从:

struct hello {
  void func() {}
};
Run Code Online (Sandbox Code Playgroud)

可能相当于:

struct hello {
  void func(this hello) {}
};
Run Code Online (Sandbox Code Playgroud)

但它们的类型不同,因为对于&hello::func,第一个给出void(hello::*)(),而第二个给出void(*)(hello)

例如,我有这个简单的功能:

struct hello {
  int data;
  void func(this hello self) {
    self.data = 22;
  }
};
Run Code Online (Sandbox Code Playgroud)

参数不需要是引用来更改类型this的值吗?hello或者它基本上和以前一样遵循成员函数的 cv-ref 限定符规则?

c++ this c++23 explicit-object-parameter

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

C++26 中是否允许 TemplatePack&lt;&gt;...[I]

包索引是在 C++26 中引入的,我希望此功能能够对元编程产生重大影响,特别是对于索引包,否则需要解决方法。

由于包索引说明符的语法是:

typedef-name ... [ expression ] 
Run Code Online (Sandbox Code Playgroud)
  • 其中typedef-nameidentifiersimple-template-id

有了上述信息,是否允许:

template <typename>
using apply_t = bool;

// #1
template <typename... Args>
using A = apply_t<Args>...[0];
// can be reworked with: apply_t<Args...[0]>

// #2
template <template <typename...> typename... Temps>
using B = Temps<>...[0]
// no other way other than this because 'Temps...[0]<>' is not allowed yet (?)
Run Code Online (Sandbox Code Playgroud)

c++ parameter-pack c++26

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

为什么 GCC 编译器不能以别名模板形式从 std::array 推导出模板参数之一

在 C++20 中,如果应用别名模板,则可以具有隐式推导指南。

然后,我构建了一个简单的模板别名ints

template <std::size_t N>
using ints = std::array<int, N>;
Run Code Online (Sandbox Code Playgroud)

但:

ints{1, 2, 3, 4}
Run Code Online (Sandbox Code Playgroud)

不起作用,GCC 说:

  • 错误:没有匹配的函数可供调用array(int, int, int, int)
  • 注意:无法推断出模板参数N
  • 注意:类型不匹配std::array<int, N>int

我不明白为什么它无法编译。

和:

template <typename T>
using array_of_4 = std::array<T, 4>;
Run Code Online (Sandbox Code Playgroud)

array_of_4{1, 2, 3, 4}
Run Code Online (Sandbox Code Playgroud)

也行不通。

  • 难道是因为std::array它的推演指南是用户提供的?
  • 如果上述答案不成立,那么原因是什么?

我发现了一个关于这个问题的类似问题:How to write deductionguides for aliases ofaggregate templates?

结论是,按照标准,该代码应该是格式良好的。因此,GCC 可能有不同的实现来阻止此代码的编译。

c++ language-lawyer template-aliases c++20 ctad

5
推荐指数
1
解决办法
242
查看次数

约束自动投射有效吗?

从 C++20 开始,约束auto是通过以下方式引入的:

Concept auto identifier = init
Run Code Online (Sandbox Code Playgroud)

这意味着,例如:

std::integral auto x = 10;
Run Code Online (Sandbox Code Playgroud)

已验证。

此外,对于新表达式,概念可以与 配对auto

new Concept auto { expr };
// or:
new Concept auto ( expr );
Run Code Online (Sandbox Code Playgroud)

auto{expr}orauto(expr)在 C++23 中引入,大致相当于:

auto __temp { expr };
return __temp;
Run Code Online (Sandbox Code Playgroud)

这是否意味着Concept auto { expr }或者Concept auto ( expr )也有效?

这个简单的用例可用于尝试创建衰减副本,同时检查其按约束检查的操作。

c++ auto c++-concepts c++23

5
推荐指数
1
解决办法
317
查看次数

为什么 std::expected 中没有一元操作?

std::optional在 C++23 中,采用了一元运算 in ,后来又采用了std::expected. 为什么像and_then、、、这样的一元操作transform没有or_else包含在主论文中?

c++ c++23 std-expected

5
推荐指数
1
解决办法
1160
查看次数