考虑以下代码:
auto f() {
const auto x = 1;
return [] (auto) { return x; };
}
Run Code Online (Sandbox Code Playgroud)
GCC 和 MSVC 编译得很好,但 Clang 拒绝了它。我应该信任哪个编译器?那是 Clang 尚未实现的编译器扩展还是只是 Clang 错误?
为了提高写入数据的性能std::string,C++23专门引入resize_and_overwrite()了std::string. 在[字符串.容量]中中,标准描述如下:
\nRun Code Online (Sandbox Code Playgroud)\ntemplate<class Operation>\nconstexpr void resize_and_overwrite(size_type n, Operation op);\n\n
让
\n\xe2\x80\x94
\no = size()在调用之前resize_and_overwrite。\xe2\x80\x94
\nk是min(o, n)。\xe2\x80\x94
\np是 acharT*,使得范围 [p,p + n] 有效并且this->compare(0, k, p, k) == 0在true调用之前。p + k[ , ]范围内的值p + n可能是不确定的[basic.indet]。\xe2\x80\x94
OP是表达式std::move(op)(p, n)。 …
目前,我已经使用 C++20约束和概念实现了分配器概念(指的是Boost 提案):
#include <concepts>
#include <iterator>
template <class A>
concept allocator =
std::copy_constructible<A> &&
std::equality_comparable<A> &&
requires(A a) {
{ a.allocate(0) } -> std::regular;
{ a.allocate(0) } -> std::constructible_from<std::nullptr_t>;
{ a.allocate(0) } -> std::equality_comparable_with<std::nullptr_t>;
{ a.allocate(0) } -> std::random_access_iterator;
{ *a.allocate(0) } -> std::same_as<typename A::value_type&>;
};
Run Code Online (Sandbox Code Playgroud)
您可以看到同一个函数有多个return-type-requirementallocate。有没有办法将它们组合成一个单一的返回类型要求,如下所示?
{ a.allocate(0) } -> std::regular &&
std::constructible_from<std::nullptr_t> &&
std::equality_comparable_with<std::nullptr_t> &&
std::random_access_iterator;
Run Code Online (Sandbox Code Playgroud) 考虑以下简单concept:
template <typename T>
concept C = requires(T a) { a.f(); };
Run Code Online (Sandbox Code Playgroud)
如果我们将抽象类类型作为requires 表达式的参数会发生什么?
struct B { virtual void f() = 0; };
static_assert(C<B>);
Run Code Online (Sandbox Code Playgroud)
gcc-trunk 和 msvc-trunk通过断言,但是,clang-trunk、gcc-10.2 和 msvc v19.24拒绝该断言。
标准怎么说?
C++23 引入了std::function的表兄弟std::move_only_function,就像它的名字一样,它是仅移动可调用对象的仅移动包装器(演示):
#include <functional>
#include <memory>
int main() {
auto l = [p = std::make_unique<int>(0)] { };
std::function<void(void)> f1{std::move(l)}; // ill-formed
std::move_only_function<void(void)> f2{std::move(l)}; // well-formed
}
Run Code Online (Sandbox Code Playgroud)
但与 不同的是std::function,该标准没有为其定义推导指南(演示):
#include <functional>
int func(double) { return 0; }
int main() {
std::function f1{func}; // guide deduces function<int(double)>
std::move_only_function f2{func}; // deduction failed
}
Run Code Online (Sandbox Code Playgroud)
禁止 CTAD 有理由吗?
考虑struct S具有operator==相同&&限定符和不同const限定符的两个重载:
struct S {
bool operator==(const S&) && {
return true;
}
bool operator==(const S&) const && {
return true;
}
};
Run Code Online (Sandbox Code Playgroud)
如果我将两者S与operator==:
S{} == S{};
Run Code Online (Sandbox Code Playgroud)
gcc 和 msvc 接受此代码,clang拒绝它:
<source>:14:7: error: use of overloaded operator '==' is ambiguous (with operand types 'S' and 'S')
S{} == S{};
~~~ ^ ~~~
Run Code Online (Sandbox Code Playgroud)
为什么 clang 认为这里有一个不明确的重载决议?在这种情况下,非常量不应该是最好的候选人吗?
同样,如果我将两个S与合成的进行比较operator!=:
S{} != S{};
Run Code Online (Sandbox Code Playgroud)
gcc 仍然接受此代码,但 msvc …
在 C++20 或 range-TS 中是否有一个已经定义的概念来指定特定类型的范围?
就像是:
template < class T, class InnerType >
concept RangeOf =
requires(T&& t) {
requires std::same_as<
std::remove_cvref_t<decltype(*std::ranges::begin(t))>,
InnerType
>;
std::ranges::end(t);
};
Run Code Online (Sandbox Code Playgroud)
允许,例如:
void print(const RangeOf<char> auto& char_seq) { /* ... */ }
Run Code Online (Sandbox Code Playgroud) 有没有一种方法可以使用 C++ 概念来要求类派生自模板化类,而模板化类的模板参数又是另一个模板化类的派生类。
例子:
template <class T>
class A{};
template <class T>
class B{};
class X{};
class Y : public A<X> {};
class Z : public B<Y> {};
Run Code Online (Sandbox Code Playgroud)
我如何办理登机手续B,这是某些人的T表格而不指定是什么?我不想添加到 的模板参数列表中,因为我不想在派生自的每个实例上更改代码(例如最后一行)。std::is_base_of<A<X>,T>XXXBBclass Z
我注意到 C++23zip_view有以下限制:
template<input_range... Views>
requires (view<Views> && ...) && (sizeof...(Views) > 0)
class zip_view;
Run Code Online (Sandbox Code Playgroud)
这意味着只能zip_view压缩输入范围。
我想知道为什么它排除output_range,因为output_range在我看来支持可能很有用。例如,我可以压缩一堆output_ranges 来同时写入,如下场景:
/* zipped input_range */
auto zip_in = views::zip(views::iota(0, 3),
views::iota(3, 6),
views::iota(6, 9));
std::vector<int> v1, v2, v3;
auto make_insert_range = [](auto inserter) {
return ranges::subrange(inserter, std::unreachable_sentinel);
};
/* zipped output_range */
auto zip_out = views::zip(make_insert_range(std::back_inserter(v1)),
make_insert_range(std::back_inserter(v2)),
make_insert_range(std::back_inserter(v3)));
/* copy */
ranges::copy(zip_in, zip_out.begin());
std::println("v1: {}", v1); // v1: [0, 1, 2]
std::println("v2: {}", …Run Code Online (Sandbox Code Playgroud) 最近意外发现gcc和msvc接受如下代码(注意template-list中的requires-clause):
#include <vector>
template <template <class> requires true class>
void f() {}
int main() {
f<std::vector>();
}
Run Code Online (Sandbox Code Playgroud)
和 clang拒绝它的语法:
<source>:3:28: error: template template parameter requires 'class' after the parameter list
template <template <class> requires true class>
^
Run Code Online (Sandbox Code Playgroud)
我应该信任哪个编译器?这段代码在语法上有效吗?
c++ ×10
c++20 ×7
c++-concepts ×5
c++23 ×3
c++17 ×2
std-ranges ×2
comparison ×1
lambda ×1
std-function ×1
string ×1
templates ×1