有条件地启用备用赋值运算符 [英] Conditional enable an alternative assignment operator
问题描述
我正试图有条件地实例化一个额外的赋值运算符。下面的代码在clang中可以正常工作,但在gcc 4.7中不能正常工作。
I'm trying to conditionally instantiate an extra assignment operator. The code below works fine in clang, but not in gcc 4.7.
我遇到的问题似乎与此处的问题非常相似: std :: enable_if有条件地编译成员函数
The problem I'm having seems very similar the the question asked here: std::enable_if to conditionally compile a member function
以下说明了我遇到的问题:
The following illustrates the problem I'm having:
#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的方式来完成此操作吗?如果是,怎么办?
Can this be done in a way which satisfies both clang and gcc 4.7? If so, how?
使用gcc时出现编译错误:
Compilations error when using 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> >’
推荐答案
您需要制作 enable_if
取决于模板参数。到目前为止,它仅取决于模板定义中的外部模板参数。但是,如果从外部模板实例化一个类,则实例化到该类的赋值运算符模板不再依赖于模板参数,因为 T
已经被替换了。
You need to make the enable_if
dependent on a template parameter. As it is now, it is only dependent on the outer template parameter within the template definition. But if you instantiate a class from the outer template, then your assignment operator template that is instantiated into that class is not dependent on a template parameter anymore because T
will have been substituted already.
只需引入一个等于 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
依赖。
Using T1
in just one of theplaces within the enable_if<...>
template arguments would suffice already, because that already makes the enable_if
dependent.
但是不是不是以前调用过您的 operator =
的电话,的声明,它与复制分配运算符冲突,因此 enable_if
在这里几乎没有用。只需将代码替换为
However it is not the call to your operator=
that was previously illformed but the declaration of it, which conflicts with the copy-assignment operator, so the enable_if
has little utility here. Just replace your code by
template<typename T1 = T>
X<T1> & operator=( const typename StrangerTypeRules <T1>::type& rhs ) {
return *this;
}
因为此 operator =
是模板,它不会与非模板重载冲突。另外,由于它是模板,因此在调用它时,如果 T
为 X< T> $ c,编译器将更喜欢非模板$ c>。
Since this operator=
is a template, it will not conflict with the non-template overload. And also because it is a template, when you call it the compiler will prefer the non-template if T
is X<T>
.
这篇关于有条件地启用备用赋值运算符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!