山寨一个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的返回值是一个函数对象. 它的源文件太长了. 看不 ...
随机推荐
- Oracle体系结构四(学习笔记)
- 算法笔记_174:历届试题 地宫取宝(Java)
目录 1 问题描述 2 解决方案 1 问题描述 问题描述 X 国王有一个地宫宝库.是 n x m 个格子的矩阵.每个格子放一件宝贝.每个宝贝贴着价值标签. 地宫的入口在左上角,出口在右下角. 小明 ...
- Eclipse Console 加大显示的行数和禁止错误弹出
在 Preferences-〉Run/Debug-〉Console里边,去掉对Limit console output的选择,或者选择,设置一下buffer size的设定值 禁止弹出: Prefer ...
- Web应用中的普通java程序获取资源文件
- LoadRunner 检查点函数总结
今天我来总结一下Loadrunner中的检查点函数,主要介绍两个函数:web_find()和web_reg_find() 这两个函数均用于内容的查找,但两者也有本质的区别,具体介绍如下: 一.web_ ...
- 【微信小程序】 引用公共js里的方法
一个小程序页面由四个文件组成,一个小程序页面的四个文件具有相同路径与文件名,由此我们可知一个小程序页面对应着一个跟页面同名的js文件.可是当有些公共方法,我们想抽离出来成为一个独立公共的js文件.我们 ...
- 原创:微信小程序调用PHP后台接口,解析纯html文本
---效果图片预览--- 1.微信js动态传参:wx.request({ url: 'https://m.****.com/index.php/Home/Xiaoxxf/activ ...
- StringBuilder.AppendFormat(String, Object, Object) 方法
将通过处理复合格式字符串(包含零个或零个以上格式项)返回的字符串追加到此实例. 每个格式项都替换为这两个参数中任意一个参数的字符串表示形式. 说明: public StringBuilder Appe ...
- POJ----The Suspects
The Suspects Time Limit: 1000MS Memory Limit: 20000K Total Submissions: 18890 Accepted: 9150 Des ...
- 概率校准Probability Calibration
在分类问题中,我们有时不仅仅需要给测试样本打上类别标签,也需要给出一个"置信度"来表示该样本属于此类别的可能性. 然而,有的分类器只能直接打上类别标签没法给出置信度.概率校准就是用 ...