![](/img/trans.png)
[英]Template class specialization with std::enable_if and a concrete type
[英]enable_if type is not of a certain template class
TLDR:見最后一段。
我有一個operator&
為幾個模板類定義,如下所示:
template <typename T>
struct Class {
Class(T const &t) { }
};
template <typename T_Lhs, typename T_Rhs>
struct ClassAnd {
ClassAnd(T_Lhs const &lhs, T_Rhs const &rhs) { }
};
template <typename T, typename T_Rhs>
ClassAnd<Class<T>, T_Rhs> operator&(Class<T> const &lhs, T_Rhs const &rhs) {
return ClassAnd<Class<T>, T_Rhs>(lhs, rhs);
}
template <typename T0, typename T1, typename T_Rhs>
ClassAnd<ClassAnd<T0, T1>, T_Rhs> operator&(ClassAnd<T0, T1> const &lhs, T_Rhs const &rhs) {
return ClassAnd<ClassAnd<T0, T1>, T_Rhs>(lhs, rhs);
}
int main() {
Class<int> a(42);
Class<double> b(3.14);
auto c = a & b;
}
這很好用。
當我想添加一個not操作時,問題就出現了,這個操作只允許在一個或另一個操作上,並且必須返回ClassAndNot
而不是ClassAnd
的實例:
template <typename T>
struct ClassNot {
ClassNot(T const &t) : value(t) { }
T value;
};
template <typename T_Lhs, typename T_Rhs>
struct ClassAndNot {
ClassAndNot(T_Lhs const &lhs, T_Rhs const &rhs) { }
};
template <typename T_Lhs, typename T_Rhs>
ClassAndNot<T_Lhs, T_Rhs> operator&(T_Lhs const &lhs, ClassNot<T_Rhs> const &rhs) {
return ClassAndNot<T_Lhs, T_Rhs>(lhs, rhs.value);
}
template <typename T_Rhs>
ClassNot<T> operator!(T_Rhs const &rhs) {
return ClassNot<T_Rhs>(rhs);
}
...
auto c = a & !b;
這導致operator&
任意右手邊返回ClassAnd
之間的歧義,以及operator&
ClassNot
右手邊返回ClassAndNot
。
題:
如何在這里使用std::enable_if
來禁用第一個operator&
如果它的右側是ClassNot
的任何類型? 是否有類似std::is_same
東西,如果一方是另一方的模板實例,則返回true?
ps你可以在ideone上找到一個完整的工作示例。
你應該能夠構建自己的特征:
template <class T>
struct IsClassNot : std::false_type
{};
template <class T>
struct IsClassNot<ClassNot<T>> : std::true_type
{};
template <typename T, typename T_Rhs>
typename std::enable_if<!IsClassNot<T_Rhs>::value,
ClassAnd<Class<T>, T_Rhs>>::type operator&(Class<T> const &lhs, T_Rhs const &rhs) {
return ClassAnd<Class<T>, T_Rhs>(lhs, rhs);
}
當然,您可以瘋狂地進行概括並創建一個通用的特征:
template <class T, template <class...> class TT>
struct is_instantiation_of : std::false_type
{};
template <template <class... > class TT, class... A>
struct is_instantiation_of<TT<A...>, TT> : std::true_type
{};
template <class T>
using IsClassNot = is_instantiation_of<T, ClassNot>;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.