10

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);
    }
};
odinthenerd
  • 5,222
  • 1
  • 28
  • 58
  • why not using `std::is_same<>` instead of `Loki::IsSameType<>` ?? – Walter Aug 07 '13 at 10:11
  • I'm programming bare metal on an ARM cortex and it was easier at first to get Loki working, so good point and I changed it ;) – odinthenerd Aug 07 '13 at 10:24
  • Do you really need a conversion operator? Or could you live with `operator=` and constructor? – Walter Aug 07 '13 at 10:39
  • `std::enable_if` has a member type(def) `type` (small `t`), not `Type`. – dyp Aug 07 '13 at 10:40
  • You could use a [`std::conditional`](http://en.cppreference.com/w/cpp/types/conditional) to switch between `Range` and `void` for the conversion operator (according to clang++, a conversion operator to `void` is legal and never used). Or you could use specialization of the class template. – dyp Aug 07 '13 at 10:44

1 Answers1

16

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);
}
Community
  • 1
  • 1
jrok
  • 52,730
  • 9
  • 104
  • 139
  • @joik thanks for pointing out my error with conflicting conversion operators, I removed it. – odinthenerd Aug 07 '13 at 11:13
  • Also note the somewhat unusual "typename = typename ...". It would not work for me if I used a type name. – Asher Nov 04 '15 at 07:10
  • C++14 introduced `std::enable_if_t` which is an alias for `typename std::enable_if<...>::type` and `std::is_same_v` for `std::is_same<...>::value`. – MSalters Oct 28 '21 at 15:48