C++11实现placeholder

文章分析如何在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

事情就变得容易一些,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. 其它类型的计算返回值类型,求值方法就是本身的类型和值。

所以可以非常容易地针对这三类结点写出处理类。另外还有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

时间: 2024-11-05 22:03:02

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

一行代码搞定UITextView的placeholder

分类已经写好,直接拿来用即可 demo: UITextView *textView = [[UITextView alloc] init]; textView.font = [UIFont systemFontOfSize:18.0]; //注意先设置字体,再设置placeholder textView.placeholder = @"请输入您的问题..."; 主要技术点: 用运行时动态绑定一个label来显示placeholder 详细代码:(已封装好的分类) 1 /** 注意先设置

IE8兼容placeholder的方案

用JavaScript解决Placeholder的IE8兼容问题 placeholder属性是HTML5新添加的属性,当input或者textarea设置了该属性后,该值的内容将作为灰色提示显示在文本框中,当文本框获得焦点时,提示文字消失,placeholder可作为输入框的提示文案 如图: placeholder是常用的属性,它使得input框内有很友好的提示效果.高版本浏览器都支持placeholder属性,但IE9以下版本的浏览器并不支持这一属性.这里用JavaScript实现添加对浏览器

(二)给IE6-IE9中的input添加HTML5新属性-placeholder

同样是最近遇到的一个小问题.因为IE9以下input是不支持placeholder属性的.在网上找到了解决方案,果断带走.正如鲁迅先生所说的‘拿来主义’:运用脑髓,放出眼光,自己来拿!感谢.借花献佛在这里记录分享下. 用法很简单,在代码中引入placeholder.js,并加入后面的一段代码就行了. 1 <script src="jquery-1.11.3.js"></script> 2 <!--IE8-IE6支持html5 placeholder新属性

读书笔记-JVM

局部变量表(虚拟机栈中的一部分)在编译期完成分配,运行期不会再改变大小: 每个方法对应一个栈帧(存储局部变量表.操作数栈.动态链接.方法出口等),栈帧被存储到虚拟机栈中,每个线程对应一个虚拟机栈,方法结束,栈帧生命周期结束,线程结束,虚拟机栈生命周期结束: 如果线程请求的虚拟机栈深度大于虚拟机所允许的深度,throw StackOverflowerror: 如果动态扩展时请求不到足够内存,throw OutOfMemoryError: 所有的对象实例以及数组都要在堆上分配(不绝对),堆是所有线程

iOS开发——完整项目实战OC篇&amp;百思不得姐第二天

百思不得姐第二天 上午 一调用父类先后顺序问题 二:手势滑动 解决问题 1 // 什么时候调用:每次触发手势之前都会询问下代理,是否触发. 2 // 作用:拦截手势触发 3 - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer 4 { 5 // 注意:只有非根控制器才有滑动返回功能,根控制器没有. 6 // 判断导航控制器是否只有一个子控制器,如果只有一个子控制器,肯定是根控制器 7 if (s

iOS核心笔记——UIAlertController

1.UIAlertController简介: ※了解:UIAlertController - - -> 提醒框控制器,在需要提醒用户执行某些操作时使用:通常分为两种样式:中间提醒框.底部提醒框. 苹果官方介绍: 2.UIAlertController使用: 2-1.UIAlertController样式: 1.UIAlertController有2种样式: 如下如所示: 2-2.UIAlertController使用步骤: UIAlertController使用alertControllerWi

asp.net MVC4 +MVCpager 无刷新分页

本人菜鸟,最近在用MVC4和MVCpager做无刷新分页时,发现点击下一页时数据不是Ajax提交的,弄了好久终于找到原因,原来还是Jquery引用的问题,现在把代码粘出来,希望能帮到刚接触的程序员,第一次自己写博客,文才不好,有什么改进的地方还希望大神多多指教. 1 using Webdiyer.WebControls.Mvc; 2 namespace MVCPage.Controllers 3 { 4 public class HomeController : Controller 5 { 6

百度地图输入一个位置到另一个位置的路线

1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 5 <title>驾车途经点</title> 6 <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min

百度回复将按时缴费卡水立方

http://www.ebay.com/cln/ch.y908/-/176925541016/2015.02.11 http://www.ebay.com/cln/shaamjson/-/176833416018/2015.02.11 http://www.ebay.com/cln/x_ru421/-/176666486019/2015.02.11 http://www.ebay.com/cln/hua6592_18usz/-/176835881012/2015.02.11 http://www