how can I use std::enable_if in a conversion opera

2019-01-19 21:46发布

问题:

Basically I want my range type to be implicitly convertible from Range<const char> to Range<const unsigned char>. std::enable_if seems impossible because the function takes no arguments and has no return. Whats the work around?

Here is basically what I tried:

template<typename T>
class Range{
    T* begin_;
    T* end_;
public:
    Range(T* begin,T* end):begin_{begin},end_{end}{}
    template<int N>
    Range(T (&a)[N]):begin_{static_cast<T*>(&a[0])},end_{static_cast<T*>(&a[N-1])}{}
    T* Begin(){return begin_;}
    T* End(){return end_;}
    operator typename std::enable_if<std::is_same<T,const char>::value,Range<const unsigned char>&>::Type (){
        return *reinterpret_cast<Range<const unsigned char>*>(this);
    }
};

回答1:

Make it a template with a dummy parameter that defaults to T - this is to postpone type deduction to the point where the function gets instantiated, otherwise SFINAE doesn't work. Then you do the check you want in default value of another parameter.

template<
    typename U = T,
    typename = typename std::enable_if< std::is_same<U,const char>::value >::type
>
operator Range<const unsigned char>() {
    return *reinterpret_cast<Range<const unsigned char>*>(this);
}