标签: c++20

std::is_convertible 和 std::convertible_to 之间的区别(在实践中)?

根据en.cppreference.com(据我所知):

  • std::is_convertible被性状类需要类型FromTo为使得与返回类型的函数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 值引用转换要求的实际影响是什么?
  • 什么样的候选人类型的FromTo附加由R值参考铸件的要求被拒绝?
  • 为什么程序员可能想要使用std::is_convertiblestd::convertible_to中的一个而不是另一个作为其函数返回类型或参数类型的约束(除了概念的便利性)?

一个更简单的解释或一个例子会有所帮助。谢谢!

c++ stl rvalue-reference c++-concepts c++20

34
推荐指数
1
解决办法
1538
查看次数

如何在Clang中使用C++模块?

模块是#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++ clang c++20 c++-modules

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

如何在可变参数模板函数中使用source_location?

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

33
推荐指数
4
解决办法
937
查看次数

为什么 volatile 在 C++20 中被弃用?

根据cppreferencevolatile关键字的大多数用法在 C++20 中将被弃用。的缺点是volatile什么?不使用时的替代解决方案是什么volatile

c++ volatile c++20

33
推荐指数
1
解决办法
4987
查看次数

lambda 表达式是合法的默认(非类型模板)参数吗?

以下所有标准参考均指N4861(2020 年 3 月布拉格后工作草案/C++20 DIS)


背景

在问答中 无捕获的 lambda 是结构类型吗?很明显,某些 lambda 表达式具有关联的闭包类型,这些闭包类型是(文字和)结构类型,因此特定的此类闭包类型可以用作非类型模板参数;本质上将结构类型 lambda 作为非类型模板参数传递。

template<auto v>
constexpr auto identity_v = v;

constexpr auto l1 = [](){};
constexpr auto l2 = identity_v<l1>;
Run Code Online (Sandbox Code Playgroud)

现在,根据[expr.prim.lambda.closure]/1 ,每个 lambda 表达式的类型都是唯一的

[...] 一个独特的、未命名的非联合类类型,称为闭包类型[...]

另一方面,[basic.def.odr]/1 [extract,强调我的]指出

任何翻译单元不得包含任何变量、函数、类类型、枚举类型、模板、参数的默认参数(对于给定范围内的函数)或默认模板参数的多个定义

可以说,默认模板参数被认为是需要尊重 ODR 的定义。

...这引出了我的问题:

  • lambda 表达式是否是合法的默认(非类型模板)参数,如果是,这是否意味着使用这种默认参数的每个实例化都会实例化一个独特的特化?

(如果接近非法,也请强调:例如,如果超出单个实例化的任何事情都会导致 ODR 违规)。


为什么?

如果这实际上是合法的,则每次调用带有 lambda 作为默认参数的变量模板都会导致唯一特化的实例化:

template<auto l = [](){}>
               // ^^^^^^ - lambda-expression as …
Run Code Online (Sandbox Code Playgroud)

c++ lambda templates language-lawyer c++20

33
推荐指数
1
解决办法
767
查看次数

大括号的类型如何影响 C++ 中的对象生命周期?

我的一个朋友给我看了一个 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 …

c++ initialization object-lifetime temporary-objects c++20

33
推荐指数
1
解决办法
1115
查看次数

C++20 constexpr 向量和字符串不起作用

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,它确实有效。该问题是否与向量相关的动态内存分配有关?

c++ stdstring visual-c++ constexpr c++20

33
推荐指数
2
解决办法
7484
查看次数

演绎指南可以有一个明确的(布尔)说明符吗?

标准的多个部分表明,推导指南不能具有显式说明符,而只能在其前面具有显式关键字。

喜欢:

temp.deduct.duide

演绎指南:

显式opt 模板名称parameter-declaration-clause)-> simple-template-id ;

请注意,该标准说:显式opt而不显式-说明符

或在dcl.fct.spec中

显式说明符,应仅在其类定义内的构造或转换函数的声明被使用; ...

但该标准还在over.match.class.deduct指出

如果函数或函数模板是从具有显式说明符的构造函数或推导中生成的,则每个这样的概念性构造函数均被视为具有相同的显式说明符

这句话暗示推导指南可以有一个明确的说明符

我没有看到为什么推理指南没有显式说明符的任何特殊原因。

是我对标准的理解还是标准本身的问题?

演绎指南可以有一个明确的(布尔)说明符吗?

c++ language-lawyer c++20

31
推荐指数
1
解决办法
688
查看次数

C ++ 20的“ char8_t”与旧的“ char”相同吗?

在CPP参考文档中

我注意到了 char

字符类型足够大,可以表示任何UTF-8八位代码单元(自C ++ 14起)

和为 char8_t

UTF-8字符表示形式的类型,必须足够大以表示任何UTF-8代码单元(8位)

这是否意味着两者是同一类型?还是char8_t有其他功能?

c++ c++14 c++20

31
推荐指数
2
解决办法
2228
查看次数

将 C 风格数组传递给 `span&lt;T&gt;`

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++ c++20

31
推荐指数
2
解决办法
3683
查看次数