根据en.cppreference.com(据我所知):
std::is_convertible被性状类需要类型From&To为使得与返回类型的函数To返回一个From值可以通过编译。std::convertible_to是一个概念,要求类型From&To如上所述,AND使得类型的r 值引用From可以转换为static_cast<To>。强加的要求std::is_convertible似乎相对简单。相反,对于 C++20 特性的简单示例中显示的这种通用概念,r 值引用转换要求std::convertible_to似乎奇怪地特定。
作为 C++ 的新手,我无法完全理解两个网页中提供的一些术语和部分补充说明,我无法想象两者的要求之间的确切区别。
一些相互关联的问题:
From& Toof 不仅受到std::is_convertible奇怪的 r 值引用转换要求的约束,而且受到奇怪的 r 值引用转换要求的实际影响是什么?From和To被附加由R值参考铸件的要求被拒绝?std::is_convertible或std::convertible_to中的一个而不是另一个作为其函数返回类型或参数类型的约束(除了概念的便利性)?一个更简单的解释或一个例子会有所帮助。谢谢!
模块是#includes的替代品.Clang有一个完整的C++实现.如果我现在想使用Clang使用模块,我该怎么办?
运用
import std.io;
Run Code Online (Sandbox Code Playgroud)
在C++源文件中还没有工作(编译),因为模块的规范(包括语法)不是最终的.
该锵文件指出,经过时-fmodules标志,#包括将被改写到相应的进口.但是,检查预处理器会另外建议(test.cpp只包含#include <stdio.h>一个空的main):
$ clang++-3.5 -fmodules -E test.cpp -o test
$ grep " printf " test
extern int printf (const char *__restrict __format, ...);
Run Code Online (Sandbox Code Playgroud)
此外,使用-fmodulesvs no flags 编译此测试文件会产生相同的目标文件.
我究竟做错了什么?
C ++ 20功能std::source_location用于捕获有关调用函数的上下文的信息。当我尝试将其与可变参数模板函数一起使用时,遇到一个问题:我看不到放置source_location参数的地方。
以下操作无效,因为可变参数必须在末尾:
// doesn't work
template <typename... Args>
void debug(Args&&... args,
const std::source_location& loc = std::source_location::current());
Run Code Online (Sandbox Code Playgroud)
以下内容也不起作用,因为调用者将被介于两者之间的参数所困扰:
// doesn't work either, because ...
template <typename... Args>
void debug(const std::source_location& loc = std::source_location::current(),
Args&&... args);
// the caller will get confused
debug(42); // error: cannot convert 42 to std::source_location
Run Code Online (Sandbox Code Playgroud)
可以在可变参数模板中无缝使用的评论中告诉我std::source_location,但是我很难弄清楚该如何做。如何std::source_location与可变参数模板函数一起使用?
c++ default-arguments variadic-templates c++20 std-source-location
根据cppreference,volatile关键字的大多数用法在 C++20 中将被弃用。的缺点是volatile什么?不使用时的替代解决方案是什么volatile?
以下所有标准参考均指N4861(2020 年 3 月布拉格后工作草案/C++20 DIS)。
在问答中 无捕获的 lambda 是结构类型吗?很明显,某些 lambda 表达式具有关联的闭包类型,这些闭包类型是(文字和)结构类型,因此特定的此类闭包类型可以用作非类型模板参数;本质上将结构类型 lambda 作为非类型模板参数传递。
Run Code Online (Sandbox Code Playgroud)template<auto v> constexpr auto identity_v = v; constexpr auto l1 = [](){}; constexpr auto l2 = identity_v<l1>;
现在,根据[expr.prim.lambda.closure]/1 ,每个 lambda 表达式的类型都是唯一的
[...] 一个独特的、未命名的非联合类类型,称为闭包类型[...]
另一方面,[basic.def.odr]/1 [extract,强调我的]指出
任何翻译单元不得包含任何变量、函数、类类型、枚举类型、模板、参数的默认参数(对于给定范围内的函数)或默认模板参数的多个定义。
可以说,默认模板参数被认为是需要尊重 ODR 的定义。
...这引出了我的问题:
(如果接近非法,也请强调:例如,如果超出单个实例化的任何事情都会导致 ODR 违规)。
如果这实际上是合法的,则每次调用带有 lambda 作为默认参数的变量模板都会导致唯一特化的实例化:
template<auto l = [](){}>
// ^^^^^^ - lambda-expression as …Run Code Online (Sandbox Code Playgroud) 我的一个朋友给我看了一个 C++20 程序:
#include <iostream>
struct A
{
A() {std::cout << "A()\n";}
~A() {std::cout << "~A()\n";}
};
struct B
{
const A &a;
};
int main()
{
B x({});
std::cout << "---\n";
B y{{}};
std::cout << "---\n";
B z{A{}};
std::cout << "---\n";
}
Run Code Online (Sandbox Code Playgroud)
在 GCC 中,它打印:
A()
~A()
---
A()
---
A()
---
~A()
~A()
Run Code Online (Sandbox Code Playgroud)
https://gcc.godbolt.org/z/ce3M3dPeo
因此,A在 y 和 z 情况下,的寿命会延长。
在 Visual Studio 中,结果是不同的:
A()
~A()
---
A()
---
A()
~A()
---
~A()
Run Code Online (Sandbox Code Playgroud)
所以A只有在 y …
constexpr std::string尝试创建and对象时出现奇怪的编译器错误std::vector:
#include <vector>
#include <string>
int main()
{
constexpr std::string cs{ "hello" };
constexpr std::vector cv{ 1, 2, 3 };
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译器抱怨“表达式必须具有常量值”:
我错过了什么吗?我使用的是最新的 Microsoft Visual Studio 2019 版本:16.11.4,并且参考(https://en.cppreference.com/w/cpp/compiler_support)指出constexpr此编译器版本支持字符串和向量:
我也尝试过constexpr std::array,它确实有效。该问题是否与向量相关的动态内存分配有关?
在CPP参考文档中,
我注意到了 char
字符类型足够大,可以表示任何UTF-8八位代码单元(自C ++ 14起)
和为 char8_t
UTF-8字符表示形式的类型,必须足够大以表示任何UTF-8代码单元(8位)
这是否意味着两者是同一类型?还是char8_t有其他功能?
C++20 引入了std::span,它是一个类似视图的对象,可以接受连续序列,例如 C 风格的数组、std::array、 和std::vector。C 风格数组的一个常见问题是在传递给函数时它会衰减为指针。这样的问题可以通过使用来解决std::span:
size_t size(std::span<int> s)
{
return s.size();
}
int main()
{
std::array arr = {1,2,3,4,5};
std::vector vec = {1,2,3,4,5};
auto il = {1,2,3,4,5};
int c_arr[] = {1,2,3,4,5};
std::cout << size(arr) << size(vec) << size(il) << size(c_arr);
}
Run Code Online (Sandbox Code Playgroud)
正如预期的那样,这将打印出来5555。然而,size可能不应该只接受int. 相反,它应该容纳任何类型的容器。但是,将 更改size为接受 a 的模板化函数后std::span<T>,它无法再成功替换 C 样式数组,而其他函数则可以:
template<typename T>
size_t size(std::span<T> s)
{
return s.size();
}
int main()
{
std::array …Run Code Online (Sandbox Code Playgroud) c++ ×10
c++20 ×10
c++-concepts ×1
c++-modules ×1
c++14 ×1
clang ×1
constexpr ×1
lambda ×1
stdstring ×1
stl ×1
templates ×1
visual-c++ ×1
volatile ×1