这里是最初始的版本,参考https://github.com/cplusplus-study/fork_stl/blob/master/include/bind.hpp 提供了最简洁的实现方式。

第一部分是bind的实现代码, 第二部分是测试代码, 对bind的实现代码中有疑问或不明白的,可参考测试代码, 测试代码基本说明了某个代码的基本含义和用途。

1. 实现

 ///////////////////////////////////////////////////////////////////////////////
// std::bind\boost::bind的山寨版本, 主要学习用.
#include <stdlib.h>
#include <type_traits>
#include <utility>
#include <tuple>
#include <functional> namespace xusd{
template <int NUM> struct placeholder{ }; template <typename T> struct is_placeholder;
template <int NUM> struct is_placeholder<placeholder<NUM> >{ enum{ value = NUM }; };
template <typename T> struct is_placeholder{ enum{ value = }; }; template <int ...N> struct seq{ };
template <unsigned N, unsigned...S> struct gen;
template <unsigned N, unsigned...S> struct gen: gen<N-, N-, S...>{ };
template <unsigned...S> struct gen<, S...>{ typedef seq<S...> type; }; template <int N, typename B, typename C>
typename std::tuple_element<
N,
typename std::decay<B>::type
>::type
select(std::false_type, B&& b, C&& c){
return std::get<N>(b);
} template <int N, typename B, typename C>
typename std::tuple_element<
is_placeholder<
typename std::tuple_element<
N,
typename std::decay<B>::type
>::type
>::value == ? :
is_placeholder<
typename std::tuple_element<
N,
typename std::decay<B>::type
>::type
>::value - ,
typename std::decay<C>::type
>::type
select(std::true_type, B&& b, C&& c)
{
return std::get<
is_placeholder<
typename std::tuple_element<
N,
typename std::decay<B>::type
>::type
>::value -
>(c);
} template <typename Fun> struct GetResult{
typedef typename std::enable_if<
std::is_class<
typename std::decay<Fun>::type
>::value,
typename GetResult<
decltype(&Fun::operator())
>::result_type
>::type result_type;
}; template <typename R, typename... Args>
struct GetResult<R(Args...)>{
typedef R result_type;
};
template <typename C, typename R, typename... Args>
struct GetResult<R(C::*)(Args...)>{
typedef R result_type;
};
template <typename C, typename R, typename... Args>
struct GetResult<R(C::*)(Args...)const>{
typedef R result_type;
}; template <typename C, typename R>
struct GetResult<R(C::*)>{
typedef decltype(((C*))->*((R(C::*)))) result_type;
}; template<typename F, typename... Args>
class bind_t {
typedef std::tuple<typename std::decay<Args>::type...> BindArgs;
typedef typename std::decay<F>::type CallFun;
enum class BindType { MemberFunction = , MemberObject = , Other = }; public:
typedef typename GetResult<
typename std::remove_pointer<
typename std::remove_reference<F>::type
>::type
>::result_type result_type; bind_t(F fun, Args... args):_fun(fun), _bindArgs(args...){ } template<typename... CArgs>
result_type operator()(CArgs&&... c){
std::tuple<CArgs...> cargs(c...);
return callFunc(
std::integral_constant<
int,
std::is_member_function_pointer<CallFun>::value ? : std::is_member_object_pointer<CallFun>::value ? :
>(),
cargs,
typename gen<
std::tuple_size<BindArgs>::value - std::is_member_function_pointer<CallFun>::value
>::type()
);
} private:
template<typename T, int ...S>
result_type callFunc(std::integral_constant<int, >, T&& t, seq<S...>) {
return _fun(
select<S>(
std::integral_constant<
bool,
is_placeholder<
typename std::tuple_element<S, BindArgs>::type
>::value !=
>(),
_bindArgs,
t)...
);
} template<typename T, int ...S>
result_type callFunc(std::integral_constant<int, >, T&& t, seq<S...>) {
return select<>(
std::integral_constant<
bool,
is_placeholder<
typename std::tuple_element<
,
BindArgs
>::type
>::value !=
>(),
_bindArgs,
t)->*_fun;
} template<typename T, int ...S>
result_type callFunc(std::integral_constant<int, >, T&& t, seq<S...>) {
return (
select<>(
std::integral_constant<
bool,
is_placeholder<
typename std::tuple_element<
,
BindArgs
>::type
>::value !=
>(),
_bindArgs,
t)->*_fun
)
(
select<S + >(
std::integral_constant<
bool,
is_placeholder<
typename std::tuple_element<
S + ,
BindArgs
>::type
>::value !=
>(),
_bindArgs,
t
)...
);
} private:
CallFun _fun;
BindArgs _bindArgs;
}; template <typename F, typename... Args>
bind_t<typename std::decay<F>::type, typename std::decay<Args&&>::type...>
bind(F f, Args&&... args){
return bind_t<
typename std::decay<F>::type,
typename std::decay<Args&&>::type...
>(f, args...);
} extern placeholder<> _1;
extern placeholder<> _2;
extern placeholder<> _3;
extern placeholder<> _4;
extern placeholder<> _5;
extern placeholder<> _6;
extern placeholder<> _7;
extern placeholder<> _8;
extern placeholder<> _9;
extern placeholder<> _10;
extern placeholder<> _11;
extern placeholder<> _12;
extern placeholder<> _13;
extern placeholder<> _14;
extern placeholder<> _15;
extern placeholder<> _16;
extern placeholder<> _17;
extern placeholder<> _18;
extern placeholder<> _19;
extern placeholder<> _20;
extern placeholder<> _21;
extern placeholder<> _22;
extern placeholder<> _23;
extern placeholder<> _24;
}

2. 测试

///////////////////////////////////////////////////////////////////////////////
// 以下开始为测试代码. #include <cstdlib>
#include <string>
#include <iostream>
#include <gtest/gtest.h> int add3(int x, int y, int z){
return x + y + z;
} std::string to_string(std::string s1, std::string s2, std::string s3){
return s1 + s2 + s3;
} int g_test_voidfun =;
void voidfun(){
g_test_voidfun = ;
} class MyTest{
public:
std::string to_string(std::string s1, std::string s2, std::string s3){
return s1 + s2 + s3;
}
int add3(int x, int y, int z){
return x + y + z;
} int cadd3(int x, int y, int z) const {
return x + y + z;
}
void voidfun(){
g_test_voidfun = ;
}
void constfun() const {
g_test_voidfun = ;
} int memObj = ;
std::string memObj2;
}; class TestAddFuncter{
public:
int operator()(int x, int y){
return x + y;
}
}; TEST(TestSeq,Test1){
using namespace xusd;
EXPECT_TRUE((std::is_same<gen<>::type, seq<> >::value));
EXPECT_TRUE((std::is_same<gen<>::type, seq<> >::value));
EXPECT_TRUE((std::is_same<gen<>::type, seq<,> >::value));
EXPECT_TRUE((std::is_same<gen<>::type, seq<,,> >::value));
EXPECT_TRUE((std::is_same<gen<>::type, seq<,,,> >::value));
EXPECT_TRUE((std::is_same<gen<>::type, seq<,,,,> >::value));
EXPECT_TRUE((std::is_same<gen<>::type, seq<,,,,,> >::value));
EXPECT_TRUE((std::is_same<gen<>::type, seq<,,,,,,> >::value));
EXPECT_TRUE((std::is_same<gen<>::type, seq<,,,,,,,> >::value));
EXPECT_TRUE((std::is_same<gen<>::type, seq<,,,,,,,,> >::value));
EXPECT_TRUE((std::is_same<gen<>::type, seq<,,,,,,,,,> >::value));
} TEST(TestPlaceHolder, Test1){
using namespace xusd;
EXPECT_TRUE((std::is_same<decltype(_1), placeholder<> >::value));
EXPECT_TRUE((std::is_same<decltype(_2), placeholder<> >::value));
EXPECT_TRUE((std::is_same<decltype(_3), placeholder<> >::value));
EXPECT_TRUE((std::is_same<decltype(_4), placeholder<> >::value));
EXPECT_TRUE((std::is_same<decltype(_5), placeholder<> >::value));
EXPECT_TRUE((std::is_same<decltype(_6), placeholder<> >::value));
EXPECT_TRUE((std::is_same<decltype(_7), placeholder<> >::value));
EXPECT_TRUE((std::is_same<decltype(_8), placeholder<> >::value));
EXPECT_TRUE((std::is_same<decltype(_9), placeholder<> >::value)); EXPECT_EQ(, (is_placeholder<int>::value));
EXPECT_EQ(, (is_placeholder<class A>::value));
EXPECT_EQ(, (is_placeholder<decltype(_1)>::value));
EXPECT_EQ(, (is_placeholder<decltype(_2)>::value));
EXPECT_EQ(, (is_placeholder<decltype(_3)>::value));
EXPECT_EQ(, (is_placeholder<decltype(_4)>::value));
EXPECT_EQ(, (is_placeholder<decltype(_5)>::value));
EXPECT_EQ(, (is_placeholder<decltype(_6)>::value));
EXPECT_EQ(, (is_placeholder<decltype(_7)>::value));
EXPECT_EQ(, (is_placeholder<decltype(_8)>::value));
EXPECT_EQ(, (is_placeholder<decltype(_9)>::value));
} TEST(TestSelectArgs, Test1){
using namespace xusd;
auto b = std::make_tuple(,_1,,_2,,_3,,_4);
auto c = std::make_tuple(,,,); EXPECT_EQ(, (select<>(std::false_type(), b, c)));
EXPECT_EQ(, (select<>(std::true_type(), b, c)));
EXPECT_EQ(, (select<>(std::false_type(), b, c)));
EXPECT_EQ(, (select<>(std::true_type(), b, c)));
EXPECT_EQ(, (select<>(std::false_type(), b, c)));
EXPECT_EQ(, (select<>(std::true_type(), b, c)));
EXPECT_EQ(, (select<>(std::false_type(), b, c)));
EXPECT_EQ(, (select<>(std::true_type(), b, c)));
} TEST(TestGetResult, Test1){
using namespace xusd; class Ret;
class C;
class Args;
class Mem;
EXPECT_TRUE((std::is_same<void,xusd::GetResult<void()>::result_type>::value));
EXPECT_TRUE((std::is_same<int,xusd::GetResult<int(int)>::result_type>::value));
EXPECT_TRUE((std::is_same<const int,xusd::GetResult<const int()>::result_type>::value));
EXPECT_TRUE((std::is_same<Ret,xusd::GetResult<Ret(Args)>::result_type>::value));
EXPECT_TRUE((std::is_same<Ret,xusd::GetResult<Ret(C::*)(Args)>::result_type>::value));
EXPECT_TRUE((std::is_same<Mem&,xusd::GetResult<Mem(C::*)>::result_type>::value)); const MyTest t1;
EXPECT_TRUE((std::is_same<int,decltype(t1.memObj)>::value));
} #define DT(x) decltype(x)
TEST(TestBind_t, Test1){
using namespace xusd;
EXPECT_TRUE((std::is_same<void, bind_t<void ()>::result_type>::value));
EXPECT_TRUE((std::is_same<void, bind_t<void (char), DT((_1))>::result_type>::value));
EXPECT_TRUE((std::is_same<void, bind_t<void (char,short), DT((_1)), DT((_2))>::result_type>::value));
EXPECT_TRUE((std::is_same<void, bind_t<void (char,short, int), DT((_1)), DT((_2)), DT((_3))>::result_type>::value));
EXPECT_TRUE((std::is_same<void, bind_t<void (char,short, int, long), DT((_1)), DT((_2)), DT((_3)), DT((_4))>::result_type>::value));
EXPECT_TRUE((std::is_same<void, bind_t<void (char,short, int, long, long long), DT((_1)), DT((_2)), DT((_3)), DT((_4)), DT((_5))>::result_type>::value)); EXPECT_TRUE((std::is_same<int, bind_t<int ()>::result_type>::value));
EXPECT_TRUE((std::is_same<int, bind_t<int (char), DT((_1))>::result_type>::value));
EXPECT_TRUE((std::is_same<int, bind_t<int (char,short), DT((_1)), DT((_2))>::result_type>::value));
EXPECT_TRUE((std::is_same<int, bind_t<int (char,short, int), DT((_1)), DT((_2)), DT((_3))>::result_type>::value));
EXPECT_TRUE((std::is_same<int, bind_t<int (char,short, int, long), DT((_1)), DT((_2)), DT((_3)), DT((_4))>::result_type>::value));
EXPECT_TRUE((std::is_same<int, bind_t<int (char,short, int, long, long long), DT((_1)), DT((_2)), DT((_3)), DT((_4)), DT((_5))>::result_type>::value)); EXPECT_TRUE((std::is_same<class AAA, bind_t<class AAA ()>::result_type>::value));
EXPECT_TRUE((std::is_same<class AAA, bind_t<class AAA (char), DT((_1))>::result_type>::value));
EXPECT_TRUE((std::is_same<class AAA, bind_t<class AAA (char,short), DT((_1)), DT((_2))>::result_type>::value));
EXPECT_TRUE((std::is_same<class AAA, bind_t<class AAA (char,short, int), DT((_1)), DT((_2)), DT((_3))>::result_type>::value));
EXPECT_TRUE((std::is_same<class AAA, bind_t<class AAA (char,short, int, long), DT((_1)), DT((_2)), DT((_3)), DT((_4))>::result_type>::value));
EXPECT_TRUE((std::is_same<class AAA, bind_t<class AAA (char,short, int, long, long long), DT((_1)), DT((_2)), DT((_3)), DT((_4)), DT((_5))>::result_type>::value)); EXPECT_TRUE((std::is_same<class AAA, bind_t<class AAA (class BBB), DT((_1))>::result_type>::value));
EXPECT_TRUE((std::is_same<class AAA, bind_t<class AAA (class BBB, class CCC), DT((_1))>::result_type>::value));
EXPECT_TRUE((std::is_same<class AAA, bind_t<class AAA (class BBB, class CCC, class DDD), DT((_1))>::result_type>::value));
EXPECT_TRUE((std::is_same<class AAA, bind_t<class AAA (class BBB, class CCC, class DDD, class EEE), DT((_1))>::result_type>::value));
EXPECT_TRUE((std::is_same<class AAA, bind_t<class AAA (class BBB, class CCC, class DDD, class EEE, class FFF), DT((_1))>::result_type>::value));
EXPECT_TRUE((std::is_same<class AAA, bind_t<class AAA (class BBB, class CCC, class DDD, class EEE, class FFF, class GGG), DT((_1))>::result_type>::value)); EXPECT_TRUE((std::is_same<class Ret, bind_t<class Ret (class Arg1), DT((_1))>::result_type>::value));
EXPECT_TRUE((std::is_same<class Ret, bind_t<class Ret (class Arg1, class Arg2), DT((_2)), DT((_1))>::result_type>::value));
EXPECT_TRUE((std::is_same<class Ret, bind_t<class Ret (class Arg1, class Arg2, class Arg3), DT((_2)), DT((_1))>::result_type>::value));
EXPECT_TRUE((std::is_same<class Ret, bind_t<class Ret (class Arg1, class Arg2, class Arg3, class Arg4),DT((_4)), DT((_1))>::result_type>::value));
EXPECT_TRUE((std::is_same<class Ret, bind_t<class Ret (class Arg1, class Arg2, class Arg3, class Arg4, class Arg5), DT((_5))>::result_type>::value));
EXPECT_TRUE((std::is_same<class Ret, bind_t<class Ret (class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6), DT((_6))>::result_type>::value));
} TEST(TestBind_t, Test2){
using namespace xusd;
bind_t<int(int, int, int), DT(_3), DT(_2), DT(_1)> t1(add3, _3, _2, _1);
EXPECT_EQ((add3(, , )), (t1(, , )));
EXPECT_EQ((add3(, , )), (t1(, , ))); bind_t<std::string(std::string, std::string, std::string), DT(_1), DT(_2), DT(_3)> s1(to_string, _1, _2, _3);
bind_t<std::string(std::string, std::string, std::string), DT(_2), DT(_3), DT(_1)> s2(to_string, _2, _3, _1);
bind_t<std::string(std::string, std::string, std::string), DT(_3), DT(_1), DT(_2)> s3(to_string, _3, _1, _2); EXPECT_EQ("", (s1("", "", "")));
EXPECT_EQ("", (s1("", "", "")));
EXPECT_EQ("", (s1("", "", "")));
EXPECT_EQ("2_3", (s1("", "_", "")));
EXPECT_EQ("", (s2("", "", "")));
EXPECT_EQ("", (s3("", "", "")));
} TEST(TestBind, NotMemberFunction){
using namespace xusd;
EXPECT_EQ((add3(, , )), (xusd::bind(add3, _3, _2, _1)(, , )));
EXPECT_EQ((add3(, , )), (xusd::bind(add3, _3, _2, _1)(, , ))); EXPECT_EQ("", (xusd::bind(to_string, _1, _2, _3)("", "", "")));
EXPECT_EQ("", (xusd::bind(to_string, _1, _2, _3)("", "", "")));
EXPECT_EQ("", (xusd::bind(to_string, _1, _2, _3)("", "", "")));
EXPECT_EQ("2_3", (xusd::bind(to_string, _1, _2, _3)("", "_", "")));
EXPECT_EQ("", (xusd::bind(to_string, _2, _3, _1)("", "", "")));
EXPECT_EQ("", (xusd::bind(to_string, _3, _1, _2)("", "", ""))); bind((voidfun))();
EXPECT_EQ(g_test_voidfun, );
} TEST(TestBind, PassToFunctional){
using namespace xusd;
EXPECT_EQ("", (std::function<std::string(std::string, std::string, std::string)>(xusd::bind(to_string, _1, _2, _3))("", "", "")));
EXPECT_EQ("", (std::function<std::string(std::string, std::string, std::string)>(xusd::bind(to_string, _1, _2, _3))("", "", "")));
EXPECT_EQ("", (std::function<std::string(std::string, std::string, std::string)>(xusd::bind(to_string, _1, _2, _3))("", "", "")));
EXPECT_EQ("2_3", (std::function<std::string(std::string, std::string, std::string)>(xusd::bind(to_string, _1, _2, _3))("", "_", "")));
EXPECT_EQ("", (std::function<std::string(std::string, std::string, std::string)>(xusd::bind(to_string, _2, _3, _1))("", "", "")));
EXPECT_EQ("", (std::function<std::string(std::string, std::string, std::string)>(xusd::bind(to_string, _3, _1, _2))("", "", "")));
} TEST(TestBind, TestMumberFunction){
using namespace xusd;
MyTest test;
EXPECT_EQ((add3(, , )), (xusd::bind(&MyTest::add3, &test, _3, _2, _1)(, , )));
EXPECT_EQ((add3(, , )), (xusd::bind(&MyTest::add3, &test, _3, _2, _1)(, , ))); EXPECT_EQ("", (xusd::bind(&MyTest::to_string, &test, _1, _2, _3)("", "", "")));
EXPECT_EQ("", (xusd::bind(&MyTest::to_string, &test, _1, _2, _3)("", "", "")));
EXPECT_EQ("", (xusd::bind(&MyTest::to_string, &test, _1, _2, _3)("", "", "")));
EXPECT_EQ("2_3", (xusd::bind(&MyTest::to_string, &test, _1, _2, _3)("", "_", "")));
EXPECT_EQ("", (xusd::bind(&MyTest::to_string, &test, _2, _3, _1)("", "", "")));
EXPECT_EQ("", (xusd::bind(&MyTest::to_string, &test, _3, _1, _2)("", "", ""))); EXPECT_EQ("", (xusd::bind(&MyTest::to_string, _4, _3, _1, _2)("", "", "", &test))); xusd::bind(&MyTest::voidfun, &test)();
EXPECT_EQ(, g_test_voidfun); xusd::bind(&MyTest::constfun, &test)();
EXPECT_EQ(, g_test_voidfun);
} TEST(TestBind, TestFuncter){
using namespace xusd;
TestAddFuncter f1;
EXPECT_EQ(, (xusd::bind(f1, _1, _2)(, )));
} TEST(TestBind, TestCFunction){
using namespace xusd;
EXPECT_EQ(, (xusd::bind(abs, _1)(-)));
} TEST(TestBind, TestMemberObj){
MyTest t1;
EXPECT_EQ(t1.memObj, );
xusd::bind(&MyTest::memObj, &t1)() = ;
EXPECT_EQ(t1.memObj, );
} int main(int argc, char* argv[]){ ::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
} namespace xusd{
placeholder<> _1;
placeholder<> _2;
placeholder<> _3;
placeholder<> _4;
placeholder<> _5;
placeholder<> _6;
placeholder<> _7;
placeholder<> _8;
placeholder<> _9;
placeholder<> _10;
placeholder<> _11;
placeholder<> _12;
placeholder<> _13;
placeholder<> _14;
placeholder<> _15;
placeholder<> _16;
placeholder<> _17;
placeholder<> _18;
placeholder<> _19;
placeholder<> _20;
placeholder<> _21;
placeholder<> _22;
placeholder<> _23;
placeholder<> _24;
}

山寨一个std::bind\boost::bind的更多相关文章

  1. boost::bind的简单实现

    前言 在上一篇blog中简单的实现了boost::function,支持带有2个参数的函数/函数指针,函数对象,函数适配器/bind类,以及带有1个参数的成员函数指针. 本文接着来介绍如何实现一个简单 ...

  2. boost::bind

    bind并不是一个单独的类或函数,而是非常庞大的家族,依据绑定的参数个数和要绑定的调用对象类型,总共有十个不同的形式,但它们的名字都叫bind. bind接受的第一个参数必须是一个可调用对象f,包括函 ...

  3. boost::bind 和 boost::function 基本用法

    这是一篇介绍bind和function用法的文章,起因是近来读陈硕的文章,提到用bind和function替代继承,于是就熟悉了下bind和function的用法,都是一些网上都有的知识,记录一下,期 ...

  4. 以boost::function和boost:bind取代虚函数

    转自:http://blog.csdn.net/Solstice/archive/2008/10/13/3066268.aspx 这是一篇比较情绪化的blog,中心思想是“继承就像一条贼船,上去就下不 ...

  5. (转)boost::bind介绍

    转自:http://www.cnblogs.com/sld666666/archive/2010/12/14/1905980.html 这篇文章介绍boost::bind()的用法, 文章的主要内容是 ...

  6. 关于boost::function与boost::bind函数的使用心得

    最近开始写一个线程池,期间想用一个通用的函数模板来使得各个线程执行不同的任务,找到了Boost库中的function函数. Boost::function是一个函数包装器,也即一个函数模板,可以用来代 ...

  7. [转] [翻译]图解boost::bind

    http://kelvinh.github.io/blog/2013/12/03/boost-bind-illustrated/ 其实这是很久之前留的一个坑了,一直没有填.. 记得在刚开始看到 boo ...

  8. 使用BOOST BIND库提高C++程序性能

    Boost.Bind为函数和函数对象,值语义和指针提供语义了一致的语法.我们首先通过一些简单的例子来看看它的基本用法,之后我们会延伸到嵌套绑定以实现功能组合.理解bind用法的一个关键是理解占位符(p ...

  9. boost::bind的使用方法

    bind - boost 头文件: boost/bind.hpp bind 是一组重载的函数模板.用来向一个函数(或函数对象)绑定某些参数. bind的返回值是一个函数对象. 它的源文件太长了. 看不 ...

随机推荐

  1. Spring boot 与quart集成并在Job中注入服务

    1:AutowiringSpringBeanJobFactory.java package com.microwisdom.grgzpt.jobs; import org.quartz.spi.Tri ...

  2. AVL树的实现例程

    /* AVL树的节点声明 */ #ifndef _AVLTREE_H #define _AVLTREE_H struct AvlNode; typedef struct AvlNode *Positi ...

  3. 解决m2e插件maven-dependency-plugin问题

    http://blog.csdn.net/smst1987/article/details/6871495 问题:maven-dependency-plugin (goals "copy-d ...

  4. tomcat thread dump 分析

    前言 Java Thread Dump 是一个非常有用的应用诊断工具, 通过thread dump出来的信息, 可以定位到你需要了解的线程, 以及这个线程的调用栈. 如果配合linux的top命令, ...

  5. c++中的友元函数

    1.友元函数的简单介绍 1.1为什么要使用友元函数 在实现类之间数据共享时,减少系统开销,提高效率.如果类A中的函数要访问类B中的成员(例如:智能指针类的实现),那么类A中该函数要是类B的友元函数.具 ...

  6. sql server 2008分页

    SELECT id, name, staffopenid, imageurl, content, ordernum, praisenum, createdate, lable, label2, man ...

  7. Oracle常用标准表

    一.INV(库存) 子库存:mtl_secondary_inventories 事物处理:mtl_material_transactions mmt 事务处理来源类型:mtl_txn_source_t ...

  8. tarfile模块可以方操作tar归档文件

    # -*- coding: utf-8 -*- #python 27 #xiaodeng #Python自带的tarfile模块可以方便读取tar归档文件 #http://www.open-open. ...

  9. CentOS6.3的VNC--远程桌面

    2G内存的服务器开启Gnome图形化界面应该没什么问题.1G还有512M的内存的就不敢开启了,现在内存正常状态就已经60%左右了. CentOS6.3服务器,Gnome图形化界面按照阿里官方步骤:一. ...

  10. 转载:substr() mb_substr() mb_subcut区别与联系

    substr() $rest = substr("abcdef", 1); //bcdef $rest = substr("abcdef", 1,5); //b ...