我已经知道这个概念是一个编译时谓词,它可以约束模板或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
当我尝试这个例子时:
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)
它会抛出编译错误。
这是缺少的功能吗?还是打算就这样离开?
我创建了一个名为的自定义容器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) 我已经阅读了最新的草案,其中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) 我阅读了此链接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++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++26 中引入的,我希望此功能能够对元编程产生重大影响,特别是对于索引包,否则需要解决方法。
由于包索引说明符的语法是:
typedef-name ... [ expression ]
Run Code Online (Sandbox Code Playgroud)
typedef-name是identifier或simple-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++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)Nstd::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++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 )也有效?
这个简单的用例可用于尝试创建衰减副本,同时检查其按约束检查的操作。
std::optional在 C++23 中,采用了一元运算 in ,后来又采用了std::expected. 为什么像and_then、、、这样的一元操作transform没有or_else包含在主论文中?
c++ ×10
c++20 ×5
c++23 ×4
c++-concepts ×3
std-ranges ×2
auto ×1
c++-modules ×1
c++26 ×1
ctad ×1
g++ ×1
std-expected ×1
this ×1
type-traits ×1