我正试图有条件地实例化一个额外的赋值运算符。下面的代码在clang中工作正常,但在gcc 4.7中没有。
我遇到的问题与此处提出的问题非常相似:std::enable_if to conditionally compile a member function
以下说明了我遇到的问题:
#include <type_traits>
template<typename T>
struct StrangerTypeRules;
template<typename T>
struct X;
template< >
struct StrangerTypeRules < unsigned > {
typedef unsigned type;
};
template< >
struct StrangerTypeRules < bool > {
typedef X<bool> type;
};
template<typename T>
struct X {
// In the non-trivial version of my code, I can not use the
// default assignment operator, therefor I need to define this one
X& operator=( const X<T>& rhs ) {
return *this;
}
// Alternative assignment oprtator, must only exists if it is
// different from the assignment operator above
template<typename =
typename std::enable_if<
( !std::is_same<
X<T>,
typename StrangerTypeRules<T>::type
>::value ),
X<T>
>::type
>
X<T> & operator=( const typename StrangerTypeRules <T>::type& rhs ) {
return *this;
}
};
int main(int argc, const char *argv[])
{
X<unsigned> x1, x2;
x1 = 4;
x2 = x1;
X<bool> x3, x4; // compile error in gcc 4.7 with -std=c++11
//x3 = x4;
return 0;
}
这可以通过满足clang和gcc 4.7的方式完成吗?如果是这样,怎么样?
使用gcc时的编译错误:
test.cxx: In instantiation of ‘struct X<bool>’:
test.cxx:52:13: required from here
test.cxx:38:12: error: no type named ‘type’ in ‘struct std::enable_if<false, X<bool> >’
答案 0 :(得分:2)
您需要使enable_if
依赖于模板参数。就像现在一样,它仅依赖于模板定义中的外部模板参数。但是,如果从外部模板实例化一个类,那么实例化到该类中的赋值运算符模板不再依赖于模板参数,因为T
已经被替换。
只需引入一个等于T
template<typename T1 = T, typename =
typename std::enable_if<
( !std::is_same<
X<T1>,
typename StrangerTypeRules<T1>::type
>::value ),
X<T1>
>::type
>
X<T1> & operator=( const typename StrangerTypeRules <T1>::type& rhs ) {
return *this;
}
在T1
模板参数中的一个位置使用enable_if<...>
已经足够了,因为这已经使enable_if
依赖。
但不对您operator=
的调用之前已经格式错误但是声明,这与复制赋值运算符冲突,所以enable_if
在这里几乎没用。只需用
template<typename T1 = T>
X<T1> & operator=( const typename StrangerTypeRules <T1>::type& rhs ) {
return *this;
}
由于此operator=
是模板,因此不会与非模板重载冲突。而且因为它是一个模板,当你调用它时,如果T
是X<T>
,编译器会更喜欢非模板。