自动转换模板< T> 到 template<const T>
Autoconverting template< T> to template<const T>
下面的这篇文章应该主要针对字符串视图,T={char, const char}
是主要的模板实例化目标。
cmp函数应该类似于strcmp
来比较视图。问题是,当char*
愉快地转换为const char*
时,我不知道如何让SVec<char>
同样愉快地转换成SVec<const char>
。
最后一行(cout<<(cmp(rv, rvc));
(不会编译。我必须显式地进行转换(cmp(SVec<const char>(rv), rvc)
(。它能像char*
到const char*
那样自动吗?
代码(大大简化(:
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));
}
因此,您可能应该做的第一件事是使cmp
成为Koenig运算符。
然后我们可以标记char和非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
是C++14,但只是typename
垃圾邮件_t
无版本的短版本。
请注意,我按值而不是const&
取值:指针和size_t
不值得通过引用传递。
我还将所有的因素归纳为2个瓶颈。
Koenig算子friend int cmp
使用ADL进行查找。它不是模板函数,而是为每个template
类实例生成的函数,这是一个重要区别。
Koenig运算符避免了模板运算符的问题,同时允许它们随模板类型的不同而变化。这样的运算符只能通过ADL(参数相关查找(找到。
然后,它根据T
在编译时是否为char
向_impl
分派重载(现在是常量正确的(。
相关文章:
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 呼叫运营商<<临时
- 如何防止clang格式在流运算符调用之间添加换行符<<
- <<操作员在下面的行中工作
- EASTL矢量<向量<int>>连续的
- C - 创建矢量&lt; vector&lt; double&gt;&gt;矩阵具有分配而不是inizializ
- 为什么将此对向量&lt; map&lt; int,int&gt;&gt;中的地图进行更新.失败
- C :对矢量进行排序&lt; struct&gt;(结构有2个整数)基于结构的整数之一
- 明确的专业化“ CheckIntmap&lt;&gt;”实例化
- 什么是模板&lt;&gt;inline bla bla
- 编辑C Qlist&lt; object*&gt; gt;QML代码和一些QML警告中的模型
- eigen :: llt&lt;eigen :: matrixxd&gt;具有不完整的类型
- 错误,包括&lt; ctype&gt;在原子上使用C 11
- std::vector<;uint8_t>;当C++11/14启用时,手动复制而不是调用memcpy
- 如何加入向量&lt; int&gt;到C 中的单个INT
- 是std :: set&lt; std :: future&gt;不可能存在
- 是numeric_limits&lt; int&gt; :: is_modulo从逻辑上矛盾
- opencv 2.4.7在iOS错误背景_segm.hpp #include&lt; list&gt;未找到
- 在修改列表后,std :: list&lt; t&gt; :: end()的值是否会更改
- ///<评论></评论>在Visual Studio中