gpt4 book ai didi

c++ - 精简概念将如何与通用引用交互?

转载 作者:可可西里 更新时间:2023-11-01 16:01:29 24 4
gpt4 key购买 nike

我最近看了this video解释 C++ 中精简概念的想法,这些概念很可能在今年作为 TS 出现。现在,我还了解了通用引用/转发引用(如 here 所述),并且 T&& 根据上下文可以有两种含义(即是否正在执行类型推导)。这自然会引出概念将如何与通用引用交互的问题?

为了使它具体化,在下面的例子中我们有

void f(int&& i) {}

int i = 0;
f(i); // error, looks for f(int&)
f(0); // fine, calls f(int&&)

template <typename T>
void f(T&& test) {}

int i = 0;
f(i); // fine, calls f(T&&) with T = int& (int& && = int&)
f(0); // fine, calls f(T&&) with T = int&& (int&& && = int&&)

但是如果我们使用概念会怎样呢?

template <typename T>
requires Number<T>
void f(T&& test) {}

template <Number T>
void g(T&& test) {}

void h(Number&& test) {}

int i = 0;
f(i); // probably should be fine?
f(0); // should be fine anyway
g(i); // probably also fine?
g(0); // fine anyway
h(i); // fine or not?
h(0); // fine anyway

尤其是最后一个例子让我有点困扰,因为有两个相互冲突的原则。首先,以这种方式使用的概念应该像类型一样工作,其次,如果 T 是推导类型,则 T&& 表示通用引用而不是右值引用。

提前感谢您对此的澄清!

最佳答案

这完全取决于概念本身是如何编写的。 Concepts-Lite 本身(latest TS 在撰写本文时)在这个问题上是不可知的:它定义了可以在语言中定义和使用概念的机制,但不向库中添加库存概念。

另一方面文档N4263 Toward a concept-enabled standard library是标准委员会的一些成员的意向声明,建议在 Concepts-Lite 之后的自然步骤是一个单独的 TS,以将概念添加到标准库中以用于约束,例如算法。

那个 TS 可能有点远,但我们仍然可以看看到目前为止是如何编写概念的。我见过的大多数例子都多少遵循了一个悠久的传统,即一切都围绕着一个假定的、通常不会被认为是引用类型的候选类型。例如,一些较旧的 Concepts-Lite 草稿(例如 N3580 )提到了 Container 等概念,它们的根源在于 SGI STL。并以 23.2 容器要求的形式在标准库中保留至今。

一个明显的预转发引用标志是关联类型的描述如下:

Value type X::value_type The type of the object stored in a container. The value type must be Assignable, but need not be DefaultConstructible.

如果我们天真地将其转换为 Concepts-Lite,它可能看起来像:

template<typename X>
concept bool Container = requires(X x) {
typename X::value_type;
// other requirements...
};

在这种情况下,如果我们写

template<typename C>
requires Container<C>
void example(C&& c);

然后我们有以下行为:

std::vector<int> v;

// fine
// this checks Container<std::vector<int>>, and finds
// std::vector<int>::value_type
example(std::move(v));

// not fine
// this checks Container<std::vector<int>&>, and
// references don't have member types
example(v);

value_type有几种表达方式优雅地处理这种情况的要求。例如。我们可以将要求调整为 typename std::remove_reference_t<X>::value_type相反。

我相信委员会成员了解情况。例如。安德鲁·萨顿 (Andrew Sutton) 留下了 insightful comment在他的概念库中展示了确切的情况。他的首选解决方案是让概念定义适用于非引用类型,并删除约束中的引用。对于我们的示例:

template<typename C>
// Sutton prefers std::common_type_t<C>,
// effectively the same as std::decay_t<C>
requires<Container<std::remove_reference_t<C>>>
void example(C&& c);

关于c++ - 精简概念将如何与通用引用交互?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29182279/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com