有条件地启用备用赋值运算符 [英] Conditional enable an alternative assignment operator

查看:70
本文介绍了有条件地启用备用赋值运算符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正试图有条件地实例化一个额外的赋值运算符。下面的代码在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>

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆