小编康桓瑋*_*康桓瑋的帖子

在模板 lambda 中隐式捕获 const 变量,而未指定捕获默认值

考虑以下代码:

auto f() {
  const auto x = 1;
  return [] (auto) { return x; };
}
Run Code Online (Sandbox Code Playgroud)

GCC 和 MSVC 编译得很好,但 Clang 拒绝了它。我应该信任哪个编译器?那是 Clang 尚未实现的编译器扩展还是只是 Clang 错误?

c++ lambda language-lawyer c++17 c++20

16
推荐指数
2
解决办法
454
查看次数

为什么 C++23 string::resize_and_overwrite 将操作作为右值调用?

为了提高写入数据的性能std::string,C++23专门引入resize_and_overwrite()std::string. 在[字符串.容量]中,标准描述如下:

\n
\n
template<class Operation>\nconstexpr void resize_and_overwrite(size_type n, Operation op);\n
Run Code Online (Sandbox Code Playgroud)\n
    \n
  1. \n

    \xe2\x80\x94o = size()在调用之前resize_and_overwrite

    \n

    \xe2\x80\x94kmin(o, n)

    \n

    \xe2\x80\x94p是 a charT*,使得范围 [ p, p + n] 有效并且this->compare(0, k, p, k) == 0true调用之前。p + k[ , ]范围内的值p + n可能是不确定的[basic.indet]

    \n

    \xe2\x80\x94OP是表达式std::move(op)(p, n)。 …

c++ string c++23

14
推荐指数
1
解决办法
934
查看次数

如何将 C++20 约束的多个返回类型要求合并为一个返回类型要求?

目前,我已经使用 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)

c++ c++-concepts c++20

13
推荐指数
2
解决办法
817
查看次数

需要带有纯抽象类类型参数的子句?

考虑以下简单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++ abstract-class language-lawyer c++-concepts c++20

13
推荐指数
1
解决办法
184
查看次数

为什么 C++23 std::move_only_function 没有推导指南?

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 有理由吗?

c++ std-function c++17 c++23

13
推荐指数
1
解决办法
2328
查看次数

用 `&amp;&amp;` 和 `const` 限定符重载 operator== 导致 C++20 中的歧义

考虑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)

如果我将两者Soperator==

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++ comparison operator-overloading language-lawyer c++20

12
推荐指数
1
解决办法
290
查看次数

特定类型的范围概念

在 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++ c++-concepts c++20 std-ranges

11
推荐指数
1
解决办法
1802
查看次数

C++ 概念:检查是否派生自具有未知模板参数的模板化类

有没有一种方法可以使用 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++ c++-concepts c++20

11
推荐指数
1
解决办法
2203
查看次数

为什么“zip_view”不支持“output_range”?

我注意到 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)

c++ std-ranges c++23

11
推荐指数
0
解决办法
232
查看次数

Requires-clause 出现在模板模板参数之后:这是合法的语法吗?

最近意外发现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++ templates language-lawyer c++-concepts c++20

10
推荐指数
1
解决办法
186
查看次数