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操作时会出现问题,该操作仅在and操作的一侧或另一侧被允许,并且必须返回
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
?如果一侧是另一侧的模板实例,是否有类似ojit_code的返回true的东西?p.s.您可以在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);
}
Live example
当然,您可以为泛化而疯狂,并创建通用的特征:
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>;
Live example
关于c++ - enable_if类型不是特定的模板类,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25803679/