【问题标题】:Why can the type constraint `std::convertible_to` be used with only one template argument?为什么类型约束 `std::convertible_to` 只能与一个模板参数一起使用?
【发布时间】:2021-10-23 10:10:44
【问题描述】:

我已经滚动并搜索了 the standard 和 cppreference 几个小时都无济于事,如果有人能为我解释这种情况,我将不胜感激:

我正在查看标准概念std::convertibe_to。这是一个我理解的简单示例

class A {};
class B : public A {};

std::convertible_to<A, B>; // false
std::convertible_to<B, A>; // true

按预期工作。

现在还有另一种可能的使用方式,我不太明白

void foo(std::convertible_to<A> auto x) { /* ... */ }

,并且这个函数可以很容易地接受任何可转换为 A 的类型。但这很奇怪,因为第一个模板参数(“From”)基本上被删除了,并在函数调用时推导出来。下面这个函数也可以工作,我很确定它实际上等同于前一个

template<typename T, std::convertible_to<T> S>
void foo(S x) { /* ... */ }

当我们调用foo 时,再次推导出x 的类型。

尽管模板需要两个参数,但这仍然有效。我也试过std::derived_from,它似乎工作。这种只用一个模板参数指定概念的形式甚至出现在标准本身中,因此必须有一些语法来解释它。

请注意,存在的std::convertible_to 中的the only version 实际上是带有两个模板参数的。

谁能解释一下为什么会这样?

【问题讨论】:

标签: c++ templates constraints c++20 c++-concepts


【解决方案1】:
void foo( constraint<P0, P1, P2> auto x );

这大致翻译为

template<contraint<P0, P1, P2> X>
void foo( X x );

大致翻译为

template<class X> requires constraint<X, P0, P1, P2>
void foo( X x );

注意X 类型是如何添加到约束的模板参数的。

所以在你的情况下,

template<typename T, std::convertible_to<T> S>
void foo(S x) { /* ... */ }

大概

template<typename T, class S>
requires std::convertible_to<S, T>
void foo(S x) { /* ... */ }

(我粗略地说,因为我认为它们在微妙的方面并不完全等同。例如,第二个引入了名称X,而第一个没有。并且可能还有其他类似规模的差异;什么我的意思是理解翻译会让你理解翻译的内容。这与for(:)循环-for(;;)循环对应不同;标准指定for(:)循环以for(;;)循环的形式,这不是我在上面声称的。)

【讨论】:

  • 最后一句:s/not like/not unlike/?
  • @Quuxplusone No. for(:) 循环被定义为将用户编写的 C++ 代码直译为 for(;;) 代码的特定位(带有一些具有秘密名称的变量)循环。这是标准的一个古怪位。据我所知,上述等价几乎没有那么直接。
  • 啊,我看到了你现在所做的区别,尽管我认为对于这种情况来说它方式太微妙了。所以我个人将其描述为“......不像,但也不像,......”;)
  • @Quuxplusone 几乎,但不完全,完全不同...
【解决方案2】:

有几个位置可以使用concept 名称,其中模板概念的第一个参数未在模板参数列表中提供。约束auto 推导变量就是其中之一。

在这些情况下,第一个参数由某个表达式提供,通常使用模板参数推导规则。在约束函数参数的情况下,第一个参数由模板函数本身确定。即如果调用foo(10),模板实参推演将auto模板形参推导出为int。因此,完整的概念将是convertible_to&lt;int, A&gt;。

【讨论】:

    猜你喜欢
    • 2022-01-22
    • 1970-01-01
    • 2021-08-13
    • 1970-01-01
    • 1970-01-01
    • 2012-04-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多