山寨一个std::bind\boost::bind
这里是最初始的版本,参考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的更多相关文章
- boost::bind的简单实现
前言 在上一篇blog中简单的实现了boost::function,支持带有2个参数的函数/函数指针,函数对象,函数适配器/bind类,以及带有1个参数的成员函数指针. 本文接着来介绍如何实现一个简单 ...
- boost::bind
bind并不是一个单独的类或函数,而是非常庞大的家族,依据绑定的参数个数和要绑定的调用对象类型,总共有十个不同的形式,但它们的名字都叫bind. bind接受的第一个参数必须是一个可调用对象f,包括函 ...
- boost::bind 和 boost::function 基本用法
这是一篇介绍bind和function用法的文章,起因是近来读陈硕的文章,提到用bind和function替代继承,于是就熟悉了下bind和function的用法,都是一些网上都有的知识,记录一下,期 ...
- 以boost::function和boost:bind取代虚函数
转自:http://blog.csdn.net/Solstice/archive/2008/10/13/3066268.aspx 这是一篇比较情绪化的blog,中心思想是“继承就像一条贼船,上去就下不 ...
- (转)boost::bind介绍
转自:http://www.cnblogs.com/sld666666/archive/2010/12/14/1905980.html 这篇文章介绍boost::bind()的用法, 文章的主要内容是 ...
- 关于boost::function与boost::bind函数的使用心得
最近开始写一个线程池,期间想用一个通用的函数模板来使得各个线程执行不同的任务,找到了Boost库中的function函数. Boost::function是一个函数包装器,也即一个函数模板,可以用来代 ...
- [转] [翻译]图解boost::bind
http://kelvinh.github.io/blog/2013/12/03/boost-bind-illustrated/ 其实这是很久之前留的一个坑了,一直没有填.. 记得在刚开始看到 boo ...
- 使用BOOST BIND库提高C++程序性能
Boost.Bind为函数和函数对象,值语义和指针提供语义了一致的语法.我们首先通过一些简单的例子来看看它的基本用法,之后我们会延伸到嵌套绑定以实现功能组合.理解bind用法的一个关键是理解占位符(p ...
- boost::bind的使用方法
bind - boost 头文件: boost/bind.hpp bind 是一组重载的函数模板.用来向一个函数(或函数对象)绑定某些参数. bind的返回值是一个函数对象. 它的源文件太长了. 看不 ...
随机推荐
- VScode-Go can't load package: package .: no buildable Go source files in
在VScode中调试Go程序时提示: can't load package: package .: no buildable Go source files in d:\my_workspace\go ...
- ionic 项目中 使用 sass
注: 1.先安装node-sass -->> npm install --save node-sass --registry=https://registry.npm.taobao.or ...
- python 读帧和绘图的区别
capture = cv2.VideoCapture(0) while True: #img = cv.QueryFrame(capture) ret, frame = capture.read() ...
- webpack 安装以及使用
1.安装webpack 全局安装代码: npm install -g webpack 2.项目中使用webpack (1)进入项目目录 cd C:\Users\dell\Documents\HBuil ...
- 安装 启动sshd服务:
.先确认是否已安装ssh服务: [root@localhost ~]# rpm -qa | grep openssh-server openssh-server-.3p1-.fc12.i686 (这行 ...
- Web 应用性能提升的 10 个建议
建议一.利用反向代理服务器加速和保护应用 如果 Web 应用运行在一台独立的电脑上,性能问题的解决方案是显而易见的:换一台更快的电脑,里面加上更多的处理器.内存.快速磁盘阵列等等.然后在这台新电脑上运 ...
- set names utf8 【mysql导入中文乱码问题解决】
由于工作的关系需要经常导入一些sql脚本,但是经常会遇到导入中文出现乱码的问题,搞得自己每次导入sql脚本时都很害怕,自己也上网找了一些资料,尝 试了许多办法,有些方法可以正常导入中文,有些办法却不行 ...
- flume的memeryChannel中transactionCapacity和sink的batchsize需要注意事项
一. fluem中出现,transactionCapacity查询一下,得出一下这些: 最近在做flume的实时日志收集,用flume默认的配置后,发现不是完全实时的,于是看了一下,原来是memery ...
- Android利用温度传感器实现带动画效果的电子温度计
概述 Android利用温度传感器实现带动画效果的电子温度计. 详细 代码下载:http://www.demodashi.com/demo/10631.html 一.准备工作 需要准备一部带有温度传感 ...
- coding云(git)远程创建版本库和上传文件
1.创建项目不讲,注意勾选 README选项 2.本地需要首先安装 windows 的git库,https://gitforwindows.org/ 3.进入www目录下,直接将coding云上的项目 ...