AutoConvert <T> to <const T> pattern

This snippet below should be mainly for the string representation of c T={char, const char}, which is the main purpose of instantiating the template.

The cmp function is supposed to compare views in a similar way strcmp. The problem is that while char*happily converting to const char*, I do not know how to get SVec<char>to convert to SVec<const char>just as happily.

The last line ( cout<<(cmp(rv, rvc));) will not compile. I have to do the conversion explicitly ( cmp(SVec<const char>(rv), rvc)). Can it be automatic, for example, from char*to const char*?

Code (greatly simplified):

template <typename T>
class SVec {
    protected:
        T* begin_;
        size_t size_;
    public:

        SVec(T* begin, size_t size)         : begin_(begin), size_(size)            {};
        SVec(T* begin, T* end)                  : begin_(begin), size_(end-begin) {};
        SVec(T* begin)                          : begin_(begin) { while (*(begin++)) {}; size_ = begin - 1 - begin_;    }
                                                //^null element indicates the end
        ///Conversion
        operator SVec<const T>() const { return SVec<const T>(begin_, size_); }
};

//General lexicographic compare
template <typename T>
inline int cmp(const SVec<const T>& l, const SVec<const T> & r){
    return 1;
}

//Char specialization
template <> inline int cmp<char>(const SVec<const char>& l, const SVec<const char>& r){
    return 1;
}
//Explicit instantiation
template int cmp<char>(const SVec<const char>& l, const SVec<const char>& r);

#include <iostream>

int main(){
    using namespace std;

    char ar[] = "st";
    SVec<char> sv = ar;
    SVec<const char> svc = "str";

    cout<<(cmp(SVec<const char>(sv), svc));

    cout<<(cmp(sv, svc));
}
+4
source share
1

, , , , , cmp Koenig.

char non char:

template <typename T>
class SVec {
  private:
    static T* find_end(T* in) {
      // I think while(*in)++in; would be better
      // then the end is the null, not one-past-the-null.
      while(*in++) {};
      return in;
    }
  protected:
    T* begin_ = nullptr;
    size_t size_ = 0;
  public:
    SVec() = default;
    SVec(SVec const&) = default;
    SVec(T* begin, size_t size) : begin_(begin), size_(size) {};
    SVec(T* begin, T* end) : SVec(begin, end-begin) {}
    SVec(T* begin) : SVec(begin, find_end(begin)) {}
    operator SVec<const T>() const { return SVec<const T>(begin_, size_); }
    friend int cmp(SVec<T> l, SVec<T> r) {
      return cmp_impl(l, r, std::is_same<std::decay_t<T>,char>{});
    }
  private:
    static int cmp_impl(SVec<const char> l, SVec<const char> r, std::true_type){
      return 1;
    }
    static int cmp_impl(SVec<const T> l, SVec<const T> r, std::false_type){
      return 1;
    }
  };

std::decay_t enable_if_t ++ 14, typename spam _t -less.

, const&: size_t .

ctors 2 .

...

Koenig friend int cmp ADL. , , template, .

Koenig , . ADL ( ).

_impl ( const-correct) if T char .

+3

Source: https://habr.com/ru/post/1609049/


All Articles