标签: c++23

模板约束与成员函数约束的功能等效性

最新的标准草案N4910在 [temp.over.link] 中有关于功能等效性的示例

template<int I> concept C = true;
template<typename T> struct A {
void f() requires C<42>; // #1
void f() requires true; // OK, different functions
};
Run Code Online (Sandbox Code Playgroud)

我的理解是,这没问题,因为C<42>true是未评估的操作数。因此,根据[temp.over.link]/5,在考虑约束是否在功能上等价时,不是表达式的结果,而是对哪个实体执行什么操作以及以什么顺序执行,才是决定约束功能等价的。

但是,如果约束在功能上等效,那么由于它们不等效,根据[temp.over.link]/7,程序将格式错误,无需诊断,因为两次声明同一成员将使程序格式错误。

另一方面

template<typename>
requires C<42>
void g() {};

template<typename>
requires true
void g() {};
Run Code Online (Sandbox Code Playgroud)

似乎格式不正确,不需要诊断,因为[temp.over.link]/6表示如果模板头接受并满足相同的模板参数,则它们在功能上是等效的。

我是否误解了示例并引用了标准措辞,或者真的有这样的差异吗?如果是这样,为什么?

c++ language-lawyer c++-concepts c++23

18
推荐指数
1
解决办法
500
查看次数

为什么std中仍然没有启用范围的归约算法?

唯一可用的选项是std::ranges::for_each简单的基于范围的for循环。没有对应的std::accumulate,std::reducestd::inner_productstd::ranges::reduce如果有的话就足够了;内积可以结合reduce和zip来实现。回到基于迭代器的算法是令人失望的。为个人代码库调整reduce并不是什么大问题,但恕我直言,std函数更可取。我想知道 std lib 或 23 地平线上是否有这样的功能。

问候,FM。

c++ std range c++23 isocpp

17
推荐指数
1
解决办法
2335
查看次数

在 lambda 中,第二个属性列表有什么作用?

C++23 允许[[...]]lambda 表达式中的属性:

auto lambda = [] [[nodiscard]]
{
    return 42;
};
Run Code Online (Sandbox Code Playgroud)

但是语法有两个属性列表,大致在参数列表之前和之后:

auto lambda = [] [[nodiscard]] () [[deprecated]]
//               (1)~~~~~~~~~~    (2)~~~~~~~~~~~  // (2) seems to have no effect here
{
    return 42;
};
Run Code Online (Sandbox Code Playgroud)

这两个列表适用于不同的事物,但我无法弄清楚第二个列表的用途,以及我可以在此处放置哪些属性。对于我在 (2) 中尝试的任何属性,Clang 警告:'...' attribute cannot be applied to types

标准是这样说的:

[expr.prim.lambda.closure]/6

... attribute-specifier-seq [位于位置 (2)] 属于相应函数调用运算符或运算符模板的类型。

attribute-specifier-seq [位于位置 (1)] 属于相应的函数调用运算符或运算符模板。

“属于相应函数调用运算符的类型”让我感到困惑。我可以在这里放置哪些属性?这是否仅适用于特定于编译器的属性?如果是,这里可以使用哪些非标准属性?

显然,列表 (2) 早在 C++23 之前就已存在(该提案添加了列表 (1))。

c++ syntax lambda c++23 c++-attributes

17
推荐指数
1
解决办法
831
查看次数

为什么在 C++23 中 allocate_at_least() ?

根据cppref

std::allocator<T>::allocate_at_least

通过调用 (可能提供附加参数)分配count * sizeof(T)未初始化存储的字节,其中 count是不小于 的未指定整数值,但未指定何时以及如何调用此函数。n::operator newstd::align_val_t

T[count]然后,该函数在存储中创建一个类型数组并开始其生命周期,但不会启动其任何元素的生命周期。

然而,我认为现有的std::allocator<T>::allocate可以做同样的事情。

为什么我们需要 std::allocator<T>::allocate_at_least C++23?

c++ performance standards allocator c++23

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

与 C++23 结合推导具有自动返回类型的 this 和转换运算符?

我最近注意到一个关于 C++23推导此功能的奇怪问题。

S假设我们有一个带有简单转换运算符的结构:

struct S {
  operator int() { return 42; }
};

int i = S{};
Run Code Online (Sandbox Code Playgroud)

由于42是 类型int,我们可以将转换运算符的返回类型指定为auto,例如:

struct S {
  operator auto() { return 42; }
};

int i = S{};
Run Code Online (Sandbox Code Playgroud)

完全没问题。如果我们应用C++23来推导它的这个特性,那就是:

struct S {
  operator auto(this S) { return 42; }
};

int i = S{};
Run Code Online (Sandbox Code Playgroud)

这也完全没问题。但是,当我替换this Sthis auto

struct S {
  operator auto(this auto) { return 42; } …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer type-deduction c++23 explicit-object-parameter

16
推荐指数
1
解决办法
879
查看次数

为什么 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++23 可选的一元绑定和一元返回是什么?

C++23std::optional终于得到了一些非常有用的补充。

由于我对 FP 的了解非常原始,我想知道以下两个操作的语法是什么(根据我的谷歌搜索,这是两个基本的一元操作):

  1. 单子绑定
  2. 单子回归

我最好的猜测是:

单子绑定就是变换

Monadic 返回只是 C++17std::optional 构造函数(8)

c++ monads stdoptional c++23

14
推荐指数
2
解决办法
2536
查看次数

C++23的可选::transform和可选::and_then有什么区别?

C++23 添加了一些关于可选值的“monadic-style”功能,作为以下方法optional<T>

optional<T>::and_then()(并忽略 的限定符this):

template<class F> constexpr auto and_then(F&& f); 
Run Code Online (Sandbox Code Playgroud)

返回对包含的值(如果存在)调用 f 的结果。否则,返回返回类型的空值。

optional<T>::transform()(并忽略 的限定符this):

template<class F> constexpr auto transform(F&& f);
Run Code Online (Sandbox Code Playgroud)

如果包含一个值,则返回一个包含对所包含值std::optional调用的结果的。否则,返回此类类型的空值。f*thisstd::optional

那么,这两个函数不是在做同样的事情吗?

c++ monads monad-transformers stdoptional c++23

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

为什么 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
查看次数

为什么可以有const赋值运算符

使用 C++23 将会有

std::pair<T1, T1>::operator =( const pair &other ) const;
Run Code Online (Sandbox Code Playgroud)

对我来说,对 const 对象进行赋值运算符没有任何意义,因为对象无法修改。为什么 C++23 在pair上有这个运算符?更令人困惑的是:

std::pair<T1, T1>::operator =( pair &&other ) const;
Run Code Online (Sandbox Code Playgroud)

[编辑]:这不起作用,因为 this 指向的内容将是 const:

template<typename T>
struct S
{
    void operator +=( T x ) const;
    T m_x;
};

template<typename T>
void S<T>::operator +=( T x ) const
{
    m_x += x;
}

int main( int argc, char **argv )
{
    S<int> si;
    si += 1;
}
Run Code Online (Sandbox Code Playgroud)

那么为什么会有一个带有pair的const限定赋值运算符呢?

c++ c++23

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