从 C++23 开始,views 不再需要是default_constructible。对于诸如views::filter和 之类的范围适配器views::transform,它们的默认构造函数被重新定义为:
template<input_\xc2\xadrange V, indirect_\xc2\xadunary_\xc2\xadpredicate<iterator_t<V>> Pred>\n requires view<V> && is_object_v<Pred>\nclass filter_view : public view_interface<filter_view<V, Pred>> {\nprivate:\n V base_ = V(); // exposition only\n copyable-box<Pred> pred_; // exposition only\npublic:\n filter_view() requires default_\xc2\xadinitializable<V> && default_\xc2\xadinitializable<Pred> = default;\n};\nRun Code Online (Sandbox Code Playgroud)\n并且因为p2325r3ref_view中已删除 的默认构造函数,这表明不再适用于左值的范围适配器:rangestd::vector default_constructible
std::vector v{1, 2, 3};\nauto r = v | std::views::filter([](auto) { return true; });\ndecltype(r){}; // ok in C++20, error in C++23\n …Run Code Online (Sandbox Code Playgroud) 关于“更简单的隐式移动”(P2266R1)提案,我不确定我是否正确理解了这个新的“符合移动条件”的东西。
如果不正确,请更正以下几点:
[直播]
std::forward 成为完美转发收到的右值参考的可选template<class T>
T&& seven(T&& x) { return std::forward<T&&>(x); }
Run Code Online (Sandbox Code Playgroud)
变成
template<class T>
T&& seven(T&& x) { return x; }
Run Code Online (Sandbox Code Playgroud)
std::move 对于本地创建的 rvalue ref 成为可选Widget&&
test_seven(Widget w) {
Widget&& rr = seven(std::move(w));
return std::move(rr);
}
Run Code Online (Sandbox Code Playgroud)
变成
Widget&&
test_seven(Widget w) {
Widget&& rr = seven(std::move(w));
return rr;
}
Run Code Online (Sandbox Code Playgroud)
std::moveoptionaly 变为parenthesis only为本地创建的事物返回一个右值引用。Widget&& h3(Widget t) {
return std::move(t);
}
Run Code Online (Sandbox Code Playgroud)
变成
Widget&& h3(Widget t) {
return (t);
}
Run Code Online (Sandbox Code Playgroud)
注意:(3) : clang …
c++ rvalue-reference move-semantics pass-by-rvalue-reference c++23
从https://github.com/gcc-mirror/gcc/commit/3acb929cc0beb79e6f4005eb22ee88b45e1cbc1d提交来看,C++ 标准头<stacktrace>存在诸如此类的东西,std::stacktrace_entry但没有声明,因为_GLIBCXX_HAVE_STACKTRACE也没有定义。
我已经在https://godbolt.org/z/b9TvEMYnh上尝试过,但是一旦我添加了参数,就会发出链接器错误-lstd++_libbacktrace(ofc,未找到)
#include <stacktrace> // header found
int main() {
// can't use features like 'std::stacktrace_entry' and 'std::stacktrace'
}
Run Code Online (Sandbox Code Playgroud)
从提交描述来看,这条消息意味着什么?:
目前,只有使用 --enable-libstdcxx-backtrace=yes 时才会构建新库。
标准中曾经有一段话指出:
除非在命名空间范围内显式声明,否则类模板特化的命名空间范围友元函数的名称在普通查找期间不可见。这些名称可以在相关类下找到。
template <typename T> struct number {
number(int);
friend number gcd(number x, number y) { return 0; }
};
void g() {
number<double> a(3), b(4);
a = gcd(a, b); // finds gcd becuase numer<double> is an associated class,
// making gcd visible in its namespace (global scope)
b = gcd(3, 4); // error: gcd is not visible
}
Run Code Online (Sandbox Code Playgroud)
此功能已用于在编译时捕获和检索元编程状态。
template <int X>
struct flag {
friend consteval int f(flag<X>);
};
template <int X, int N>
struct injecter { …Run Code Online (Sandbox Code Playgroud) 在std::ranges::to论文 wg21.link/p1206 中,概述部分有以下内容
//Supports converting associative container to sequence containers
auto f = ranges::to<vector>(m);
Run Code Online (Sandbox Code Playgroud)
但是我找不到std::map论文其余部分描述转换为 a 的细节的地方。我尝试了 range-v3 和 Sy Brandranges::to在https://github.com/TartanLlama/ranges中的实现,但它们都没有编译将范围转换为std::map.那么,这只是这些库中缺失的还是转换为std::map并非真正允许的?
std::begin.begin如果参数有成员函数,则可以调用该成员函数。似乎也std::ranges::begin做同样的事情。
但是,在 的 页面上,std::ranges::contains我没有看到提及member一词,也没有看到.contains. 这是为什么?
我的意思是,如果我要写,std::ranges::contains(someRange, someVal)我真的希望它会导致对 member 的调用contains,如果someRange碰巧是 astd::map和someVala key 。
我还查看了ranges::containsRange-v3,在我看来,它也只是在范围内进行线性搜索,对支持 member 的参数没有特殊处理contains。
C++20 和 C++23 引入了迭代器对和范围的模板构造函数std::string_view。std::span有类似的构造函数。
template<class It, class End>
constexpr basic_string_view(It first, End last); // C++20
template<class R>
explicit constexpr basic_string_view(R&& r); // C++23
Run Code Online (Sandbox Code Playgroud)
该文档包含参数的要求。为什么这些要求没有定义为C++20 概念约束?这不会导致更好的错误消息吗?
我已经有一段时间没有在 StackOverflow 上发布任何问题了;我希望我或多或少记住了解决问题的适当方式(提前抱歉)。
\n我正在使用 C++ 流和 FMT 库,它提供了 C++23 打印的预览。当设置填充符来完成整数的显示宽度时,流很冷。例子:
\nconst int y = 730;\ncout << "y = " << setw(5) << y << endl;\ncout << "y = " << setfill('0') << setw(5) << y << endl;\ncout << "y = " << setfill('X') << setw(5) << y << endl;\ncout << "y = " << setfill('*') << setw(5) << y << endl;\nRun Code Online (Sandbox Code Playgroud)\n输出是
\ny = 730\ny = 00730\ny = XX730\ny = **730\nRun Code Online (Sandbox Code Playgroud)\n我试图使用 fmt::print\xe2\x80\x94 设置相同的填充符(包括“X”和“*”字符),例如:
\n …以下代码片段在 C++23 中合法吗?
#include <memory>
#include <cstdio>
int main()
{
struct custom_deleter
{
static void operator()(int* const ptr)
{
delete ptr;
std::fputs( "Deleted\n", stdout );
}
};
auto ptr { std::unique_ptr<int, decltype(&custom_deleter::operator())> {new int {5},
custom_deleter::operator()} };
}
Run Code Online (Sandbox Code Playgroud)
GCC 似乎对此很满意。不过我想知道它是否符合标准。
另外,为什么删除&from会decltype(&custom_deleter::operator())导致编译错误?这是否意味着Deleter类型模板参数必须是函数指针类型(在本例中void(*)(int*))?
我想专门讨论两件事。一个int, 以及任何类型的指针。int但现在让我们坚持下去。
在下面的代码中, ifT是 an int,我想要一个Test::a()返回 0 的不同实现。我尝试过:
template<>
int a() { return 0; }
Run Code Online (Sandbox Code Playgroud)
但这显然是错误的,因为我收到一个编译错误,表明我写的内容毫无意义。
我有办法做到这一点吗?Test如果我想做这样的事情,我需要专注于所有事情吗?
我真正的类有几百行,所以如果可能的话,我宁愿只重新实现一两个函数。
template<class T>
class Test{
T*t;
public:
Test(T*t) : t(t) {}
T a() { return 1; }
T b() { return 2; }
//if T == int
//int a() { return 0; }
};
int main(int argc, char *argv[])
{
Test<int> t(0);
return t.a();
}
Run Code Online (Sandbox Code Playgroud) c++ ×10
c++23 ×10
std-ranges ×3
c++20 ×2
templates ×2
c++-concepts ×1
fmt ×1
friend ×1
libstdc++ ×1
performance ×1
unique-ptr ×1