std :: is_convertible中的std :: decay是否冗余?

dasfex

我写了这样的代码:

template <class T>
class A {
  template <class U, class = 
class std::enable_if_t<std::is_convertible_v<std::decay_t<U>, std::decay_t<T>>>>
      void f(U&& val) {}
    };

我希望该类的用户f只能使用可转换为的类型进行调用T

std::decay多余的吗?如果删除它,也许我会错过一些特殊情况?

克里斯·乌兹达维尼斯

我认为您的问题更具哲学性,例如:在C ++中的类型范围中,在以下情况下,在T和U的任何情况下,调用f()和g()都有明显的区别:

template <class T>
struct A {
 
    template <
        class U, 
        enable_if_t<is_convertible_v<decay_t<U>, decay_t<T>>>* = nullptr
    >
    void f(U&& val) {}

    template <
        class U, 
        enable_if_t<is_convertible_v<U, T>>* = nullptr
    >
    void g(U&& val) {}
};

衰减_t实际做什么?

  • 删除顶级const / volatile限定符
  • 删除顶级参考限定符
  • 数组->指针转换
  • 函数->函数指针转换

可能值得注意的是:衰减_t是根据传递给函数时函数参数类型发生的情况建模的。因此,decay_t<U>应始终等价于U(前提是模板推导机制未使用显式模板参数来颠覆。)

因此,我们只需要关注decay_t<T>并仔细考虑以下情况:

  • T可以转换为T&吗?(没有)
  • 函数指针可以转换为函数类型吗?(没有)
  • T *可以转换为T []吗?(没有)
  • T可以转换为const T吗?(是)

因此,我们应该能够构造案例来证明这些观察结果:

// T is ARRAY type
A<int[]> a1; 
int ary[] = {1,2,3};
a1.f(ary);  // OK
a1.g(ary);  // ERROR (U decays to T*)

// T is REFERENCE type
A<int&> a2;
a2.f(123);  // OK
a2.g(123);  // ERROR (U decays to int)

// T is FUNCTION type
A<void()> a3;
a3.f(foo);  // OK
a3.g(foo);  // ERROR (U decays to void(*)()

// T is const type
A<const int> a4;
a4.f(123);  // OK
a4.g(123);  // OK

因此,是的,在某些情况下,衰减的值无法返回,并且由于U隐式衰减,因此当T不衰减时,在某些情况下可能会遇到一些错误。

您可以安全地移除decay_tU关闭,但是在T上则有所不同。

实时观看https://godbolt.org/z/P5P64Y

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

std :: is_convertible和std :: convertible_to(在实践中)之间的区别?

为什么std :: string似乎执行了std :: is_convertible说不可能的事情?

什么是std :: decay,什么时候应该使用?

std :: is_convertible与std :: function不一致

std :: string()与std :: string(“”)是否相同

std :: cout是否被缓冲?

std :: is_convertible的可变版本?

在C ++ 17中使用转发引用时,模板结构是否需要std :: decay?

为什么在<utility> std :: pair(STL)中在这里“ is_convertible”?

什么时候std :: is_convertible认为原始类型是可转换的?

std :: decay和std :: remove_reference之间的区别

std :: endl << std :: flush是否有目的?

为什么出于std :: is_convertible的目的boost :: optional <T>无法转换为bool

是std :: is_convertible协变还是逆变?

是否有与std :: array等效的std :: memset?

std :: vector是否将std :: tuple和std :: tuple <std :: tuple>视为相同类型?

std :: is_base_of和std :: is_convertible之间的区别

使用std :: is_convertible和std :: type_index

在std :: list中,std :: distance(it.begin(),std :: prev(it.end()))是否等于list.size()?

是否可以在std :: any中存储引用?

std :: decay和删除const限定词

是否需要在noexcept运算符中进行std :: decay?

在std :: forward中使用std :: decay

是否在std :: chrono :: duration中定义了std :: ratio计算顺序?

std :: reverse是否具有冗余操作?

是否可以从std :: abort中恢复?

使用clang时,std :: is_convertible中没有名为value的成员

`std::find()` 是否短路?

std::variant 聯合中是否允許 std::vector ?