我写了这样的代码:
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实际做什么?
可能值得注意的是:衰减_t是根据传递给函数时函数参数类型发生的情况建模的。因此,decay_t<U>
应始终等价于U(前提是模板推导机制未使用显式模板参数来颠覆。)
因此,我们只需要关注decay_t<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_t
U的关闭,但是在T上则有所不同。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句