SFINAE启用非模板成员函数 [英] SFINAE to enable nontemplate member function

查看:237
本文介绍了SFINAE启用非模板成员函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这可能是一个重复,但我只是不能找到一个OP明显有相同的问题我有。

我有一个类,我试图启用 operator - 仅当类模板参数不是无符号类型时。

  #include< type_traits> 

template< class T>
struct A {
typename std :: enable_if<!std :: is_unsigned< T> :: value,A> :: type operator-(){return {};}
};

int main(){
A< unsigned> a = a;不幸的是,这会产生一个编译器错误,无论何时用无符号类型实例化它。如下所示。

  main.cpp:5:29:error:在'std :: enable_if& false,A< unsigned int> >'; 'enable_if'不能用于禁用此声明
typename std :: enable_if<!std :: is_unsigned< T> :: value,A> :: type operator-(){return {};}
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ unsigned int>'这里请求
A< unsigned> a = a;
^

好吧,我可以清楚地看到 enable_if 不会在这里工作。一个模糊的类似问题提到我可以使用继承和模板专门化来解决这个问题,但是...真的没有更好的方法吗?

解决方案

有点长的注释:您也可以使用自由函数,即使是一元运算符。

  #include< ; type_traits> 

template< class T>
struct A {
};

template< class T>
typename std :: enable_if<!std :: is_unsigned< T> :: value,A< T> :: type
operator-(A< T>){return {};}

int main(){
A< signed> b;
-b; // ok

A< unsigned>一个;
-a; // error
}

这不会为每个类模板引入成员函数模板






您可以通过以下方式与他们取得联系:

  template< class T> 
class A {
int m;

public:
A(T p):m(p){}

template< class U>
friend
typename std :: enable_if<!std :: is_unsigned< U> :: value,A< U>> :: type
operator-(A&
};

template< class T>
typename std :: enable_if<!std :: is_unsigned< T> :: value,A< T>> :: type
operator-(A< T> p){return {pm} }

int main(){
A< signed> b(42)。
-b; // ok

A< unsigned> a(42);
// - a; // error
}


$ b $ p

你可以(应该)向前声明函数模板。


This is probably a duplicate, but I just can't find one where the OP clearly has the same problem I'm having.
I have a class, and I'm trying to enable operator- only if the class template parameter is not an unsigned type.

#include <type_traits>

template<class T>
struct A {
    typename std::enable_if<!std::is_unsigned<T>::value,A>::type operator-() {return {};}
};

int main() {
    A<unsigned> a=a;
}

Unfortunately, this produces a compiler error any time I instantiate it with an unsigned type as shown.

main.cpp:5:29: error: no type named 'type' in 'std::enable_if<false, A<unsigned int> >'; 'enable_if' cannot be used to disable this declaration
    typename std::enable_if<!std::is_unsigned<T>::value,A>::type operator-() {return {};}
                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~
main.cpp:9:17: note: in instantiation of template class 'A<unsigned int>' requested here
    A<unsigned> a=a;
                ^

Well, I can clearly see that enable_if is not going to work here. One vaguely similar question mentioned I can use inheritance and template specialization to work around this, but... is there really no better way?

解决方案

A bit long for a comment: You can also use a free function, even for unary operators.

#include <type_traits>

template<class T>
struct A {
};

template<class T>
typename std::enable_if<!std::is_unsigned<T>::value,A<T>>::type
operator-(A<T>) {return {};}

int main() {
    A<signed> b;
    -b; // ok

    A<unsigned> a;
    -a; // error
}

This doesn't introduce a member function template for each class template.


Here's how you can befriend it:

template<class T>
class A {
    int m;

public:
    A(T p) : m(p) {}

    template<class U>
    friend
    typename std::enable_if<!std::is_unsigned<U>::value,A<U>>::type
    operator-(A<U>);
};

template<class T>
typename std::enable_if<!std::is_unsigned<T>::value,A<T>>::type
operator-(A<T> p) {return {p.m};}

int main() {
    A<signed> b(42);
    -b; // ok

    A<unsigned> a(42);
    //-a; // error
}

You can (should) forward-declare that function template, though.

这篇关于SFINAE启用非模板成员函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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