文章分析怎样在C++11中实现简单的placeholder。

首先看看什么是placeholder:

for_each(arr.begin(), arr.end(), cerr << _0 << endl);

当中arr的类型是vector<int>,第三个參数是一个表达式,表达式中有一个操作数是_0。第三个參数含义是对这个表达式进行求值,得到一个对象x,x拥有operator ()(int a)的成员函数。整个表达式意味着把arr的每个元素b取出来。然后调用x(b)。而x(b)的效果是将b输出到一行当中。当中的_0就是placeholder,在表达式中作为一个占位符存在,等待外部给出_0的类型和值的时候,整个表达式再求值。



这是个非常酷的语法糖。在C++11中能够用lambda表达式取代,只是弄明确怎么实现对于模板元编程的能力会有所提升。以下来分析一下怎样去实现placeholder:



考虑_0, _1这些占位符,首先搞明确它们在C++中的语法成份。出如今表达式中,并且表达式不是处于某个模板的环境。能够肯定在编译时能知道表达式的全部操作数的类型。

_0能够是一个形如被定义为make_placeholder0()的宏。也能够是T0 _0;之类的一个对象。只是这没有关系,我们仅仅关心_0这个表达式的类型。能够看出_0应该具有类类型。operator << 能作用于该类型的对象上。

占位符和其他操作数进行运算,会产生新的类型,新的类型还能够參加运算,最后使得cerr << _0 << endl这个表达式具有某个类型。我们假定这个产生的新的类型是TExpr。TExpr在运算后仍然是TExpr类型。假设把语法树的结点用类型标注一下,对于表达式_0 + _1 -
_2应该是例如以下结果

- : TExpr

               + : TExpr      _2 : T2

_0 : T0  _1 : T1

TExpr将拥有operator ()。可以求值。可是眼下看来TExpr上的operator () 具有不确定性:

根结点上,operator将使用两个操作数。把减法操作应用在两个操作数上。

在左边的结点上,是将加法应用在两个操作数上。

所以TExpr中的operator ()是多态的。

假设将语法树改为:

                       - : TExpr<MinusTag>

               + : TExpr<AddTag>      _2 : T2

         _0 : T0  _1 : T1

事情就变得easy一些,TExpr是參数化的,依据不同的Tag參数,在operator ()时有不同的行为。



能够预见我们应该构造一堆这种类:

template<typename L, typename R, typename T>
class TExpr; template<typename L, typename R>
class TExpr<L, R, AddTag>
{
L left_operand;
R right_operand;
}; template<typename L, typename R>
class TExpr<L, R, SubTag>
{
L left_operand;
R right_operand;
};

当中L,R两个类型可能是T0。T1等占位符的类型,或者是TExpr<,,,>,或者是其他类型。可是这样做有个缺点。把參数个数写死了。于是将上面的AddTag和TExpr组合到一起,形成

template<typename T1, typename T2>
struct TExprAdd
{
};
template<typename T1, typename T2>
struct TExprSub
{
};

进一步,将_0和_1的类型定义为:

template<int v>
struct TExprBasic
{
};

并提供操作:

template<typename T1, typename T2>
TExprAdd<T1, T2>
operator + (T1 a, T2 b)
{
typedef TExprAdd<T1, T2> TI;
return TI(a, b);
} template<typename T1, typename T2>
TExprSub<T1, T2>
operator - (T1 a, T2 b)
{
typedef TExprSub<T1, T2> TI;
return TI(a, b);
}

于是语法树变为:





                        - : TExprSub<TExprAdd<TExprBasic<0>, TExprBasic<1>>, TExprBasic<2>>

                + : TExprAdd<TExprBasic<0>, TExprBasic<1>>          _2 : TExprBasic<2>

     _0 : TExprBasic<0>  _1 : TExprBasic<1>



至此,我们已经给出了一个能够用的placeholder的架构了。



我们要求TExprAdd,TExprSub拥有一些共性,满足某个concept,这个concept就是TExpr。这个concept是自己在编程中心中默默建立的。当然也能够把这个concept用显式的方式写出来:

<pre name="code" class="cpp">template<typename T>
class TExpr
{
// require 1:T具有计算返回类型的元函数get_result_type
template<typename TUPLE>
struct get_result_type
{
typedef typename T::template get_result_type<TUPLE> Impl;
typedef typename Impl::result_type result_type;
}; // require 2:T的对象应该具有operator () 成员函数模板,用于求值
template<typename... Arg>
auto operator () (Arg... arg)->typename get_result_type<std::tuple<Arg...>>::result_type
{
return impl.template operator () (std::forward<std::tuple<TL...>>(t));
} T impl;
}; template<typename T1, typename T2>
TExpr<TExprAdd<T1, T2> >
operator + (T1 a, T2 b)
{
typedef TExprAdd<T1, T2> TI;
return TExpr<TI>(TI(a, b));
} template<typename T1, typename T2>
TExpr<TExprSub<T1, T2> >
operator - (T1 a, T2 b)
{
typedef TExprSub<T1, T2> TI;
return TExpr<TI>(TI(a, b));
}


这样就相当于描写叙述了一个TExpr接口,有若干个详细实现:TExprBasic。TExprAdd,TExprSub等。[在这里接口的描写叙述体如今TExpr对模板參数类型的依赖。要求T包括什么样的类型,要求T的对象有什么样的操作。接口的实现体如今把TExpr<...>作为TExpr的模板參数。]嗯。也就是表达式模板技术。

于是我们的语法树中的-和+结点的类型分别变为:

TExpr<TExprAdd<TExprBasic<0>, TExprBasic<1>>>和TExpr<TExprSub<TExprAdd<TExprBasic<0>, TExprBasic<1>>, TExprBasic<2>>>添加TExpr优点是,语法树中的结点被分为三类:TExpr<...>。TExprBasic<...>。以及其他。这三类结点要求可以计算返回类型,求值。

首先明白计算的输入和输出,返回类型的输入是变长模板參数,返回一个返回类型,求值的输入是tuple,返回一个值。而三种类型的编译时和执行时求值策略非常清楚:1.
TExpr能够直接依赖于模板參数。计算返回值类型,求值。2. TExprBasic能够直接计算返回值类型(输入变长模板參数,返回该模板參数某个位置上的类型),直接求值(输入tuple,返回tuple中某一项)。

3. 其他类型的计算返回值类型,求值方法就是本身的类型和值。

所以能够很easy地针对这三类结点写出处理类。另外还有TExprAdd之类的类没有处理。这类结点的返回值类型计算须要分别计算其左操作数和右操作数的类型,然而在C++11中我们能够方便地用decltype(TA()+TB())来进行处结果的类型推导。而求值也是分别计算左右操作数的值,然后中间填上一个相应的操作符,作为一个表达式返回。[另外。还能够把TExprBasic作为TExpr的參数,这样全部的结点类型仅仅剩下TExpr和其他类型了,更加方便管理。这个包装过程仅仅须要改改代码就可以。

只是不改也能体现出一种思想,TExpr是递归的。TExprBasic是原子的,其他类型是原子的。]在此基础上,还引入两类print函数。没有參数的能输出带占位符的语法树。有參数的能输出带很多其他信息的语法树。

#include <iostream>
#include <tuple>
#include <vector>
#include <algorithm>
using namespace std; template<int v>
struct int_{enum{value=v};}; template<typename T>
struct value_of{enum{value=-1};}; template<int v>
struct value_of<int_<v>>{enum{value=v};}; template<typename V1, typename V2>
struct max_type
{
template<typename VA, typename VB, bool>
struct max_type_impl
{
typedef VA result_type;
};
template<typename VA, typename VB>
struct max_type_impl<VA, VB, true>
{
typedef VB result_type;
};
enum{value1=value_of<V1>::value, value2=value_of<V2>::value};
typedef typename max_type_impl<V1, V2, (value1<value2)>::result_type result_type;
}; template<typename T>
struct TExpr
{ TExpr(T o) : v(o){} template<typename TUPLE>
struct get_result_type
{
typedef typename T::template get_result_type<TUPLE> Impl;
typedef typename Impl::result_type result_type;
};
template<typename... Arg>
auto operator () (Arg... arg)->typename get_result_type<std::tuple<Arg...>>::result_type
{
return this->template evalue(std::tuple<Arg...>(arg...));
}
template<typename... TL>
auto evalue(std::tuple<TL...>&& t)->typename get_result_type<std::tuple<TL...>>::result_type
{
return v.template evalue(std::forward<std::tuple<TL...>>(t));
}
template<typename... Arg>
void print(Arg... arg)
{
this->template print(tuple<Arg...>(arg...));
}
template<typename... TL>
void print(std::tuple<TL...>&& t)
{
v.template print(std::forward<std::tuple<TL...>>(t));
}
void print()
{
v.print();
}
T v;
}; template<int v>
struct TExprBasic
{
template<typename TUPLE>
struct get_result_type
{
typedef typename std::tuple_element<v, TUPLE>::type result_type;
};
template<typename... TL>
auto evalue(std::tuple<TL...>&& t)->typename get_result_type<std::tuple<TL...>>::result_type
{
return std::get<v>(std::forward<std::tuple<TL...>>(t));
}
template<typename... TL>
void print(std::tuple<TL...>&& t)
{
cout << std::get<v>(std::forward<std::tuple<TL...>>(t));
}
void print()
{
cout << v;
}
}; template<typename T>
struct is_expr
{
enum{value=false};
};
template<typename T>
struct is_expr<TExpr<T>>
{
enum{value=true};
};
template<int v>
struct is_expr<TExprBasic<v>>
{
enum{value=true};
}; template<typename T, typename TUPLE>
struct get_result_type
{
typedef T result_type;
};
template<typename T, typename TUPLE>
struct get_result_type<TExpr<T>, TUPLE>
{
typedef typename TExpr<T>::template get_result_type<TUPLE>::result_type result_type;
};
template<int v, typename TUPLE>
struct get_result_type<TExprBasic<v>, TUPLE>
{
typedef typename TExprBasic<v>::template get_result_type<TUPLE>::result_type result_type;
}; template<typename T>
struct print_helper_t
{
typedef int_<is_expr<T>::value> U; print_helper_t(T a) : x(a){} void print()
{
print_impl(U());
}
void print_impl(int_<1>)
{
x.print();
}
void print_impl(int_<0>)
{
cout << x;
}
template<typename... TL>
void print(std::tuple<TL...>&& t)
{
print_impl(std::forward<std::tuple<TL...>>(t), U());
}
template<typename... TL>
void print_impl(std::tuple<TL...>&& t, int_<1>)
{
x.print(std::forward<std::tuple<TL...>>(t));
}
template<typename... TL>
void print_impl(std::tuple<TL...>&& t, int_<0>)
{
cout << x;
}
T x;
};
template<typename T>
print_helper_t<T> print_helper(T x)
{
return print_helper_t<T>(x);
} template<typename T, typename TUPLE>
struct value_helper_t
{
typedef int_<is_expr<T>::value> U;
typedef typename ::get_result_type<T, TUPLE>::result_type result_type; value_helper_t(T a) : x(a){} template<typename... TL>
result_type value(std::tuple<TL...>&& t)
{
return value_impl(std::forward<std::tuple<TL...>>(t), U());
}
template<typename... TL>
result_type value_impl(std::tuple<TL...>&& t, int_<1>)
{
return x.template evalue(std::forward<std::tuple<TL...>>(t));
}
template<typename... TL>
result_type value_impl(std::tuple<TL...>&& t, int_<0>)
{
return x;
}
T x;
};
template<typename T, typename TUPLE>
value_helper_t<T, TUPLE> value_helper(T x)
{
return value_helper_t<T, TUPLE>(x);
} template<typename T1, typename T2>
struct TExprAdd
{ TExprAdd(T1 a, T2 b) : x(a), y(b){} template<typename TUPLE>
struct get_result_type
{
typedef typename ::get_result_type<T1, TUPLE>::result_type TA;
typedef typename ::get_result_type<T2, TUPLE>::result_type TB;
typedef decltype(TA()+TB()) result_type;
};
template<typename... TL>
auto evalue(std::tuple<TL...>&& t)-> typename get_result_type<std::tuple<TL...>>::result_type
{
return value_helper<T1, std::tuple<TL...>>(x).template value(std::forward<std::tuple<TL...>>(t)) +
value_helper<T2, std::tuple<TL...>>(y).template value(std::forward<std::tuple<TL...>>(t));
}
template<typename... TL>
void print(std::tuple<TL...>&& t)
{
cout << "(";
print_helper(x).template print(std::forward<std::tuple<TL...>>(t));
cout << " + ";
print_helper(y).template print(std::forward<std::tuple<TL...>>(t));
cout << ")";
}
void print()
{
cout << "(";
print_helper(x).template print();
cout << " + ";
print_helper(y).template print();
cout << ")";
}
T1 x;
T2 y;
}; template<typename T1, typename T2>
struct TExprSub
{ TExprSub(T1 a, T2 b) : x(a), y(b){} template<typename TUPLE>
struct get_result_type
{
typedef typename ::get_result_type<T1, TUPLE>::result_type TA;
typedef typename ::get_result_type<T2, TUPLE>::result_type TB;
typedef decltype(TA()-TB()) result_type;
};
template<typename... TL>
auto evalue(std::tuple<TL...>&& t)-> typename get_result_type<std::tuple<TL...>>::result_type
{
return value_helper<T1, std::tuple<TL...>>(x).template value(std::forward<std::tuple<TL...>>(t)) -
value_helper<T2, std::tuple<TL...>>(y).template value(std::forward<std::tuple<TL...>>(t));
}
template<typename... TL>
void print(std::tuple<TL...>&& t)
{
cout << "(";
print_helper(x).template print(std::forward<std::tuple<TL...>>(t));
cout << " - ";
print_helper(y).template print(std::forward<std::tuple<TL...>>(t));
cout << ")";
}
void print()
{
cout << "(";
print_helper(x).template print();
cout << " - ";
print_helper(y).template print();
cout << ")";
}
T1 x;
T2 y;
}; template<typename T1, typename T2>
struct TExprMul
{ TExprMul(T1 a, T2 b) : x(a), y(b){} template<typename TUPLE>
struct get_result_type
{
typedef typename ::get_result_type<T1, TUPLE>::result_type TA;
typedef typename ::get_result_type<T2, TUPLE>::result_type TB;
typedef decltype(TA()*TB()) result_type;
};
template<typename... TL>
auto evalue(std::tuple<TL...>&& t)-> typename get_result_type<std::tuple<TL...>>::result_type
{
return value_helper<T1, std::tuple<TL...>>(x).template value(std::forward<std::tuple<TL...>>(t)) *
value_helper<T2, std::tuple<TL...>>(y).template value(std::forward<std::tuple<TL...>>(t));
}
template<typename... TL>
void print(std::tuple<TL...>&& t)
{
cout << "(";
print_helper(x).template print(std::forward<std::tuple<TL...>>(t));
cout << "*";
print_helper(y).template print(std::forward<std::tuple<TL...>>(t));
cout << ")";
}
void print()
{
cout << "(";
print_helper(x).template print();
cout << "*";
print_helper(y).template print();
cout << ")";
}
T1 x;
T2 y;
}; template<typename T1, typename T2>
struct TExprDiv
{ TExprDiv(T1 a, T2 b) : x(a), y(b){} template<typename TUPLE>
struct get_result_type
{
typedef typename ::get_result_type<T1, TUPLE>::result_type TA;
typedef typename ::get_result_type<T2, TUPLE>::result_type TB;
typedef decltype(TA()/TB()) result_type;
};
template<typename... TL>
auto evalue(std::tuple<TL...>&& t)-> typename get_result_type<std::tuple<TL...>>::result_type
{
return value_helper<T1, std::tuple<TL...>>(x).template value(std::forward<std::tuple<TL...>>(t)) /
value_helper<T2, std::tuple<TL...>>(y).template value(std::forward<std::tuple<TL...>>(t));
}
template<typename... TL>
void print(std::tuple<TL...>&& t)
{
cout << "(";
print_helper(x).template print(std::forward<std::tuple<TL...>>(t));
cout << "/";
print_helper(y).template print(std::forward<std::tuple<TL...>>(t));
cout << ")";
}
void print()
{
cout << "(";
print_helper(x).template print();
cout << "/";
print_helper(y).template print();
cout << ")";
}
T1 x;
T2 y;
}; template<typename T1, typename T2>
struct TExprComma
{ TExprComma(T1 a, T2 b) : x(a), y(b){} template<typename TUPLE>
struct get_result_type
{
typedef typename ::get_result_type<T1, TUPLE>::result_type TA;
typedef typename ::get_result_type<T2, TUPLE>::result_type TB;
typedef TB result_type;
};
template<typename... TL>
auto evalue(std::tuple<TL...>&& t)-> typename get_result_type<std::tuple<TL...>>::result_type
{
value_helper<T1, std::tuple<TL...>>(x).template value(std::forward<std::tuple<TL...>>(t));
return value_helper<T2, std::tuple<TL...>>(y).template value(std::forward<std::tuple<TL...>>(t));
}
template<typename... TL>
void print(std::tuple<TL...>&& t)
{
cout << "(";
print_helper(x).template print(std::forward<std::tuple<TL...>>(t));
cout << " , ";
print_helper(y).template print(std::forward<std::tuple<TL...>>(t));
cout << ")";
}
void print()
{
cout << "(";
print_helper(x).template print();
cout << " , ";
print_helper(y).template print();
cout << ")";
}
T1 x;
T2 y;
}; template<typename T1, typename T2>
struct TExprShiftLeft
{ TExprShiftLeft(T1 a, T2 b) : x(a), y(b){} template<typename TUPLE>
struct get_result_type
{
typedef typename ::get_result_type<T1, TUPLE>::result_type TA;
typedef typename ::get_result_type<T2, TUPLE>::result_type TB;
typedef TA result_type;
};
template<typename... TL>
auto evalue(std::tuple<TL...>&& t)-> typename get_result_type<std::tuple<TL...>>::result_type
{
return value_helper<T1, tuple<TL...>>(x).template value(std::forward<std::tuple<TL...>>(t)) <<
value_helper<T2, tuple<TL...>>(y).template value(std::forward<std::tuple<TL...>>(t));
}
template<typename... TL>
void print(std::tuple<TL...>&& t)
{
typedef typename get_result_type<tuple<TL...>>::result_type result_type;
output("(", int_<std::is_integral<result_type>::value>());
print_helper(x).template print(std::forward<std::tuple<TL...>>(t));
cout << " << ";
print_helper(y).template print(std::forward<std::tuple<TL...>>(t));
output(")", int_<std::is_integral<result_type>::value>());
}
void print()
{
//output("(", int_<std::is_integral<result_type>::value>());
print_helper(x).template print();
cout << " << ";
print_helper(y).template print();
//output(")", int_<std::is_integral<result_type>::value>());
}
void output(const char* s, int_<1>)
{
cout << s;
}
void output(const char* s, int_<0>)
{
}
T1 x;
T2 y;
}; template<typename T>
struct TExprShiftLeft<ostream, T>
{
TExprShiftLeft(ostream& a, T b) : x(a), y(b){} template<typename TUPLE>
struct get_result_type
{
typedef ostream& result_type;
};
template<typename... TL>
auto evalue(std::tuple<TL...>&& t)->typename get_result_type<std::tuple<TL...>>::result_type
{
return x << value_helper<T, tuple<TL...>>(y).template value(std::forward<std::tuple<TL...>>(t));
}
template<typename... TL>
void print(std::tuple<TL...>&& t)
{
cout << "cout << ";
y.print(std::forward<std::tuple<TL...>>(t));
}
void print()
{
cout << "xout << ";
y.print();
}
ostream& x;
T y;
}; template<typename T1, typename T2>
TExpr<TExprAdd<T1, T2> >
operator + (T1 a, T2 b)
{
typedef TExprAdd<T1, T2> TI;
return TExpr<TI>(TI(a, b));
} template<typename T1, typename T2>
TExpr<TExprSub<T1, T2> >
operator - (T1 a, T2 b)
{
typedef TExprSub<T1, T2> TI;
return TExpr<TI>(TI(a, b));
} template<typename T1, typename T2>
TExpr<TExprMul<T1, T2> >
operator * (T1 a, T2 b)
{
typedef TExprMul<T1, T2> TI;
return TExpr<TI>(TI(a, b));
} template<typename T1, typename T2>
TExpr<TExprDiv<T1, T2> >
operator / (T1 a, T2 b)
{
typedef TExprDiv<T1, T2> TI;
return TExpr<TI>(TI(a, b));
} template<typename T1, typename T2>
TExpr<TExprComma<T1, T2> >
operator , (T1 a, T2 b)
{
typedef TExprComma<T1, T2> TI;
return TExpr<TI>(TI(a, b));
} template<typename T>
TExpr<TExprShiftLeft<ostream, TExpr<T> > >
operator << (ostream& out, TExpr<T> x)
{
typedef TExprShiftLeft<ostream, TExpr<T>> TI;
return TExpr<TI>(TI(out, x));
} template<int T>
TExpr<TExprShiftLeft<ostream, TExprBasic<T> > >
operator << (ostream& out, TExprBasic<T> x)
{
typedef TExprShiftLeft<ostream, TExprBasic<T>> TI;
return TExpr<TI>(TI(out, x));
} template<typename T1, typename T2>
TExpr<TExprShiftLeft<TExpr<T1>, T2>>
operator << (TExpr<T1> e, T2 x)
{
typedef TExprShiftLeft<TExpr<T1>, T2> TI;
return TExpr<TI>(TI(e, x));
} template<int v, typename T1>
TExpr<TExprShiftLeft<TExprBasic<v>, T1>>
operator << (TExprBasic<v> e, T1 x)
{
typedef TExprShiftLeft<TExprBasic<v>, T1> TI;
return TExpr<TI>(TI(e, x));
} #define MAKE(x) TExprBasic<x> _ ## x
MAKE(0);MAKE(1);MAKE(2);MAKE(3);MAKE(4);MAKE(5);MAKE(6);MAKE(7);MAKE(8);MAKE(9); int main()
{
auto add = _0 + _1;
cout << add(string("123"), "456") << endl;
cout << add((int*)0, 1) << endl;
cout << add("12345678", 1) << endl; auto test = (cerr << ((_0 << _1) + _2 * 0 - _1 / _2) << "___" << _3 << "___" << (int*)&main, cerr << _0, 1);
test.print();
cout << endl;
test.print(4, 5, 6, string("c++"));
cout << endl << "=";
test(4, 5, 6, "hello world");
cout << endl; int init = 0;
vector<int> vec(8);
for_each(vec.begin(), vec.end(), [&](int& a){a=++init;});
for_each(vec.begin(), vec.end(), cout << _0);
return 0;
}

C++11实现placeholder的更多相关文章

  1. html5高级

    Html5高级 项目回顾 Day 01 第三阶段知识体系: (1)AJAX异步请求 数据库.PHP.HTTP.原生AJAX.jQuery中的AJAX (2)HTML5高级特性 九大新特性 (3)Boo ...

  2. 读书笔记-JVM

    局部变量表(虚拟机栈中的一部分)在编译期完成分配,运行期不会再改变大小: 每个方法对应一个栈帧(存储局部变量表.操作数栈.动态链接.方法出口等),栈帧被存储到虚拟机栈中,每个线程对应一个虚拟机栈,方法 ...

  3. js 获取验证码计时器

    效果图: 贴上代码: <div class="logintitle"> <input type="tel" id="mobile&q ...

  4. vue使用技巧:Promise + async + await 解决组件间串行编程问题

    业务场景描述 大家都通过互联网投递过简历,比如在智联.58.猎聘等平台.投递心仪的职位前一般都需要前提创建一份简历,简历编辑界面常规的布局最上面是用户的个人基本信息,如姓名.性别.年龄.名族等,接着是 ...

  5. 【后台管理系统】—— Ant Design Pro组件使用(二)

    一.关联表单项 - 动态增删输入框Input        封装子组件 class ParamsInputArray extends React.Component{ constructor(prop ...

  6. Element Form表单实践(上)

    作者:小土豆biubiubiu 博客园:https://www.cnblogs.com/HouJiao/ 掘金:https://juejin.im/user/58c61b4361ff4b005d9e8 ...

  7. 地区sql

    /*Navicat MySQL Data Transfer Source Server : localhostSource Server Version : 50136Source Host : lo ...

  8. c++11模拟boost元占位符placeholder

    准备实现meta programming的fold函数,发现自己缺少占位符实现,这样传入fold的transform op类(元函数)都不得不另外写个外覆类,其实我觉得没啥不好,简单直接,说实话干扰什 ...

  9. placeholder不兼容 IE10 以下版本的解决方法

    对于密码输入框placeholder的兼容问题:HTML代码:<input type="password" id="loginPassword" plac ...

随机推荐

  1. Kinect 开发 —— 面部追踪

    SDK1.5中新增了人脸识别类库:Microsoft.Kinect.Toolkit.FaceTracking使得在Kinect中进行人脸识别变得简单,该类库的源代码也在Developer Toolki ...

  2. reboot---重启Linux系统

    reboot命令用来重新启动正在运行的Linux操作系统. 语法 reboot(选项) 选项 -d:重新开机时不把数据写入记录文件/var/tmp/wtmp.本参数具有“-n”参数效果: -f:强制重 ...

  3. 今日SGU 5.4

    SGU 127 题意:给你n个数字,和m,k,问你有多少个数字的m次幂可以被k整除 收获:快速幂 #include<bits/stdc++.h> #define de(x) cout< ...

  4. [Unit testing] data-test attr FTW

    Most of time, we get used to use class name as a selector in the test. But one problem for this is c ...

  5. activity-启动动画的设定(下面弹出出现,弹入下面消失)

    1.今天为了把一个activity以dialog的形式显示,而且实现从开始的时候从底部往上弹出,结束的时候,从上往下消失,做了如下的工作. 1)如果把一个activity以dialog的形式显示? 这 ...

  6. Google Web Toolkit(GWT) 在windows下环境搭建

    1.什么是GWT? Google Web Toolkit(简称GWT,读作/ˈɡwɪt/),是一个前端使用JavaScript,后端使用Java的AJAX framework,以Apache许可证2. ...

  7. elasticsearch选举master

    数据节点确定了master以后.会开启MasterPinger线程来与其保持心跳通信的逻辑假设通信过程中链接断开,会通过MasterNodeFailureListener监听器进行回调处理处理过程中会 ...

  8. “ping”命令的原理就是向对方主机发送UDP数据包,HTTP在每次请求结束后都会主动释放连接,因此HTTP连接是一种“短连接”

    Socket  是一套建立在TCP/IP协议上的接口不是一个协议 应用层:  HTTP  FTP  SMTP  Web 传输层:  在两个应用程序之间提供了逻辑而不是物理的通信(TCP  UDP) T ...

  9. fromCharCode vs chr

    fromCharCode vs chr echo off set "fn=%*" set php=d:/www/php5/php.exe cls echo. %php% %fn% ...

  10. es6常用功能与异步详解(JS高级面试题)

    callback hell方法的使用 可读性不友好 function loadImg(src,callback,fail){ var img = document.createElement('img ...