类型特征的模板特化,其中类型根据条件改变
Template specialization for type traits where the type change depending on conditional
假设我们有一个给定的 class ABC
,它的模板是 K
和 V
:
template <typename K, typename V>
using ABC = AnotherClass<K, V>
我知道可以实现类型特征来检查模板 T
是否属于给定的 class ABC
,例如:
template <typename T>
struct is_class_abc : std::false_type {};
template <typename K, typename V>
struct is_class_abc<ABC<K, V>> : std::true_type {};
假设我们将 ABC
定义更改为 AnotherClass
,类型根据 K
和 V
:
template <typename K, typename V>
using ABC = AnotherClass<typename std::conditional<
CONDITION, SOMETHING, SOMETHIN_ELSE>::type, ... >
条件,东西和something_else都依赖于K-V
我得到这个编译错误:
Class template partial specialization contains template parameters that cannot be deduced; this partial specialization will never be used
Non-deducible template parameter 'K'
与 V
相同。
知道是否可以这样做吗?如果是这样,我该如何让它发挥作用?
偏特化不仅会检查传递的类型是否为 ABC<K,V>
形式,还会 try/need 推导 K
和 V
。现在让我们看看它是如何工作的。假设我们传递类型特征应该检查 ABC<K, V>
。由于 ABC
只是类型别名,因此传递给此类型特征的实际类型实际上是 AnotherClass<K',V'>
形式,其中 K'
和 V'
是 [=12 的一些修改=] 和 V
.
现在类型特征需要从K'
和V'
推导出K
和V
,这确实是必要的,因为有可能没有例如 K
和 V
。但是由于您使用了 std::conditional<...>::type
,因此对于编译器来说那里发生的事情并不透明。这称为非推导上下文。基本上,在一些简单的情况下我们可以向后推导(例如,如果你有 ABC = AnotherClass<const K, V>
)。在许多情况下(例如当您在另一个类型中使用 typedef 时,就像这里一样)这是可能的 complicated/not。
这并不总是直观的,有时令人费解,例如这里:
template<class>
struct is_const : std::false_type {};
template<class T>
struct is_const<const T> : std::true_type {}; // This works
template<class T>
struct is_const<typename add_const<T>::type> : std::true_type {}; // This does NOT work
第二个特化也只添加了一个 const,例如 const T
,但这是隐藏的(也就是在非推导上下文中),因此我们无法推导 T
.
假设我们有一个给定的 class ABC
,它的模板是 K
和 V
:
template <typename K, typename V>
using ABC = AnotherClass<K, V>
我知道可以实现类型特征来检查模板 T
是否属于给定的 class ABC
,例如:
template <typename T>
struct is_class_abc : std::false_type {};
template <typename K, typename V>
struct is_class_abc<ABC<K, V>> : std::true_type {};
假设我们将 ABC
定义更改为 AnotherClass
,类型根据 K
和 V
:
template <typename K, typename V>
using ABC = AnotherClass<typename std::conditional<
CONDITION, SOMETHING, SOMETHIN_ELSE>::type, ... >
条件,东西和something_else都依赖于K-V
我得到这个编译错误:
Class template partial specialization contains template parameters that cannot be deduced; this partial specialization will never be used
Non-deducible template parameter 'K'
与 V
相同。
知道是否可以这样做吗?如果是这样,我该如何让它发挥作用?
偏特化不仅会检查传递的类型是否为 ABC<K,V>
形式,还会 try/need 推导 K
和 V
。现在让我们看看它是如何工作的。假设我们传递类型特征应该检查 ABC<K, V>
。由于 ABC
只是类型别名,因此传递给此类型特征的实际类型实际上是 AnotherClass<K',V'>
形式,其中 K'
和 V'
是 [=12 的一些修改=] 和 V
.
现在类型特征需要从K'
和V'
推导出K
和V
,这确实是必要的,因为有可能没有例如 K
和 V
。但是由于您使用了 std::conditional<...>::type
,因此对于编译器来说那里发生的事情并不透明。这称为非推导上下文。基本上,在一些简单的情况下我们可以向后推导(例如,如果你有 ABC = AnotherClass<const K, V>
)。在许多情况下(例如当您在另一个类型中使用 typedef 时,就像这里一样)这是可能的 complicated/not。
这并不总是直观的,有时令人费解,例如这里:
template<class>
struct is_const : std::false_type {};
template<class T>
struct is_const<const T> : std::true_type {}; // This works
template<class T>
struct is_const<typename add_const<T>::type> : std::true_type {}; // This does NOT work
第二个特化也只添加了一个 const,例如 const T
,但这是隐藏的(也就是在非推导上下文中),因此我们无法推导 T
.