我发现 std::visit 可以按以下方式使用:
std::visit([](auto&& arg) {
using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same_v<T, int>)
std::cout << "int with value " << arg << '\n';
else if constexpr (std::is_same_v<T, std::string>)
std::cout << "std::string with value " << std::quoted(arg) << '\n';
else
static_assert(always_false_v<T>, "non-exhaustive visitor!");
}, v);
Run Code Online (Sandbox Code Playgroud)
但相反,我想我也可以使用
if(auto x = std::get_if<int>(&v))
std::cout << " is int " << *x << std::endl;
else if(auto x = std::get_if<std::string>(&v))
std::cout << " is String " << *x << std::endl;
else
std::cout << "non-exhaustive visitor!" …Run Code Online (Sandbox Code Playgroud) 考虑需要表达式:
constexpr auto b = requires { []{}; };
Run Code Online (Sandbox Code Playgroud)
GCC通过以下两个static_assert:
static_assert(b);
static_assert(!b);
Run Code Online (Sandbox Code Playgroud)
这看起来非常奇怪。我希望 的值b应该是true。这只是一个 GCC 错误吗?
考虑以下无用的代码:
struct S{
constexpr operator int() const { return 0; }
constexpr auto operator<=>(S) const { return *this; }
};
static_assert(S{} <= S{});
Run Code Online (Sandbox Code Playgroud)
Clang 和 MSVC 接受此代码,但 GCC拒绝它并显示错误消息:
error: no match for 'operator<=' (operand types are 'S' and 'int')
Run Code Online (Sandbox Code Playgroud)
哪个编译器是对的?是怎么operator<=合成的operator<=>?
c++ language-lawyer implicit-conversion spaceship-operator c++20
根据[view.interface],非常量和常量重载data函数定义如下:
template<class D>
requires is_class_v<D> && same_as<D, remove_cv_t<D>>
class view_interface : public view_base {
private:
constexpr D& derived() noexcept { // exposition only
return static_cast<D&>(*this);
}
constexpr const D& derived() const noexcept { // exposition only
return static_cast<const D&>(*this);
}
public:
constexpr auto data() requires contiguous_iterator<iterator_t<D>> {
return to_address(ranges::begin(derived()));
}
constexpr auto data() const
requires range<const D> && contiguous_iterator<iterator_t<const D>> {
return to_address(ranges::begin(derived()));
}
};
Run Code Online (Sandbox Code Playgroud)
为什么data() const需要另外满足const D是 a ranges::range?不是iterator_t<const …
C++20带来了更强大的迭代器系统,其中之一就是iterator_concept在iterator_category.
我发现C++20 中很多迭代器的iterator_concept和iterator_category是不一致的。以最著名iota_view的为例:
using R = decltype(views::iota(0));
static_assert(random_access_range<R>);
using I = ranges::iterator_t<R>;
static_assert(same_as<typename I::iterator_category, input_iterator_tag>);
static_assert(same_as<typename I::iterator_concept, random_access_iterator_tag>);
Run Code Online (Sandbox Code Playgroud)
虽然是Rmodels random_access_range,但iterator_category它的迭代器的the只是一个input_iterator_tag,与iterator_concept.
为什么C++20引入iterator_concept?它的目的是什么?如果我实现我自己的迭代器,我该如何界定iterator_concept和iterator_category正确?是否iterator_category仍然在C ++ 20的意思?
考虑以下内容,它使用三元运算符来获取两个 lambda 的公共函数指针类型
int main() {
true ? [](auto) noexcept {} : [](int) {};
}
Run Code Online (Sandbox Code Playgroud)
GCC-trunk 仅在 C++14 中接受它,但在 C++17/20 中拒绝它(演示):
<source>:2:8: error: operands to '?:' have different types 'main()::<lambda(auto:1)>' and 'main()::<lambda(int)>'
2 | true ? [](auto) noexcept {} : [](int) {};
| ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)
Clang-trunk 在所有 C++14/17/20 模式下接受它(演示)。
MSVC-trunk 仅在 C++20 中接受它,但在 C++14/17 中拒绝它(演示):
<source>(2): error C2446: ':': no conversion from 'main::<lambda_01e5bb79b5a210014fb78333f6af80f9>' to 'main::<lambda_57cf6f5767bc1bee4c1e1d9859a585d2>'
<source>(2): note: No user-defined-conversion operator available that can perform this …Run Code Online (Sandbox Code Playgroud) 我可以使用运行时以 std::format 定义的格式字符串吗?
这似乎是在说你不能;所有格式字符串都是编译时的事情。我可以发誓我是在几个月前才这么做的,也许是在标准回归之前。
#include <iostream>
#include <string>
#include <format>
std::string centre(std::string& string, const int width, const char fillchar = ' '){
if (width <= string.size())
return string;
string = std::format("|{0:{1}^{2}}|", string, fillchar, width); //line 25
return string;
}
int main() {
std::cout << centre(s, 10, '*');
}
Run Code Online (Sandbox Code Playgroud)
在构建时,我收到错误
string.cpp(25,24): 错误 C7595: 'std::_Basic_format_string<char,row::string::str &,const size_t &,const char &>::_Basic_format_string': 对立即函数的调用不是常量表达
考虑以下两个过载operator<=>为S:
#include <compare>
struct S {};
int operator<=>(S, int) { return 0; } #1
S operator<=>(S, S) { return {}; } #2
Run Code Online (Sandbox Code Playgroud)
如果我比较的对象S有int,在#1将产生正确的运营商对我来说,这么喜欢表达S{} <= 0,0 < S{}或0 <=> S{}将只是罚款。
但是,如果我将一个对象S与其他对象进行比较S:
S{} < S{};
Run Code Online (Sandbox Code Playgroud)
那么这将被重写为(S{} <=> S{}) < 0. 既然(S{} <=> S{})会返回 other S,我们回到原点问题:S与 a 进行比较int。目前,我们没有operator<(S, int),因此#1 …
这是我的代码:
if constexpr (requires { { N::uuid() } -> std::convertible_to<score::uuid_t>; })
Run Code Online (Sandbox Code Playgroud)
clang-format (14, 15) 坚持将其格式化为 5 行:
if constexpr (requires {
{
N::uuid()
} -> std::convertible_to<score::uuid_t>;
})
Run Code Online (Sandbox Code Playgroud)
这太疯狂了,我怎样才能确保它保持在一行上而不必注释每一行?
我被分配了一项任务,需要在考虑到几个限制的情况下解决问题。重点是强制使用 STL 算法、迭代器和新的 c++20 功能,包括ranges. 然而,我已经阅读了几个小时的范围,但我仍然无法弄清楚如何在考虑到所有限制的情况下实现该问题。我简化了问题并删除了具体细节以使其更加通用。
问题:
编写一个函数,该函数 1) 接受自定义对象的向量2) 返回不同类型input的向量,其中包含满足某些条件的每个对象的元素。添加的值基于输入对象的属性。input
我意识到这可能听起来很晦涩,所以这里有一个简单的例子。对于形状的输入向量,其中每个形状都有一个名称和一个区域:
vector<Shapes> input{ { "Square", 10 }, { "Triangle", 30 } , { "Square", 1 }, { "Circle", 30 }, { "Triangle", 15 } };
Run Code Online (Sandbox Code Playgroud)
返回枚举向量
enum Color { RED, BLUE, GREEN };
Run Code Online (Sandbox Code Playgroud)
这样为每个 Square 或 Circle 添加一个枚举。枚举的值是根据每个 Shape 的面积确定的。因此,假设面积大于 20,则添加红色,否则添加绿色。
所以在这种情况下我们会返回{ GREEN, GREEN, RED }
这一切都很好,可以通过多种方式实施,但限制因素使其变得非常困难。
限制条件:
std::for_eachstd::vector我的教授声称“c++20 范围使这项任务特别简单”。但即使在阅读了几个小时的范围后,我什至不知道该从哪里开始。我当前的思路是创建 a …
c++ ×10
c++20 ×9
std-ranges ×3
lambda ×2
c++-concepts ×1
c++17 ×1
clang-format ×1
iterator ×1
noexcept ×1
range-v3 ×1
stdformat ×1
variant ×1