CSDN上看到有人问能否实现一个效率较高的max函数,效率接近于宏,于是自动动手写了一个。
由于max宏在判断不同类型时,能够返回大的那个类型(表示范围大),所以只能使用模板来进行返回类型的推导。
在VC8上打开O2或Ox优化选项,测试结果是与宏效率相等。
全部实现如下:
#include
<
typeinfo
>
#include
<
cassert
>
#include
<
windows.h
>
#include
<
iostream
>
template
<
class
T,
class
U,
bool
B
>
struct
BigType
{
typedef T result;
};
template
<
class
T,
class
U
>
struct
BigType
<
T, U,
false
>
{
typedef U result;
};
template
<
class
T,
class
U
>
struct
Type
{
typedef typename BigType
<
T, U, (
sizeof
(T)
>
sizeof
(U))
>
::result BigType;
};
template
<
class
T
>
struct
Type
<
T,
double
>
{
typedef
double
BigType;
};
template
<
class
T
>
struct
Type
<
double
, T
>
{
typedef
double
BigType;
};
template
<
class
T
>
struct
Type
<
T,
float
>
{
typedef
float
BigType;
};
template
<
class
T
>
struct
Type
<
float
, T
>
{
typedef
float
BigType;
};
template
<>
struct
Type
<
double
,
float
>
{
typedef
double
BigType;
};
template
<>
struct
Type
<
float
,
double
>
{
typedef
double
BigType;
};
template
<
class
T,
class
U
>
typename Type
<
T, U
>
::BigType MaX (
const
T
&
t,
const
U
&
u)
{
typedef typename Type
<
T, U
>
::BigType ResultType;
return
ResultType(t
>
u
?
t : u);
//
原为return (ResultType)t > u ? t : u;
}
int
main ()
{
assert (typeid(MaX(
1
,
2
))
==
typeid(
int
));
assert (MaX(
1
,
2
)
==
2
);
assert (typeid(MaX(
1
,
2.5
))
==
typeid(
double
));
assert (MaX(
1
,
2.5
)
==
2.5
);
assert (typeid(MaX(
1
, (
float
)
2.5
))
==
typeid(
float
));
assert (MaX(
1
, (
float
)
2.5
)
==
2.5
);
assert (typeid(MaX((
double
)
2
, (
float
)
2.5
))
==
typeid(
double
));
assert (MaX((
double
)
2
, (
float
)
2.5
)
==
2.5
);
assert (typeid(MaX((
long
)
2
, (
float
)
2.5
))
==
typeid(
float
));
assert (MaX((
long
)
2
, (
float
)
2.5
)
==
2.5
);
assert (typeid(MaX((
long
)
2
, (
short
)
2
))
==
typeid(
long
));
assert (MaX((
long
)
2
, (
short
)
2
)
==
2
);
assert (typeid(MaX((
float
)
2
, (__int64)
2
))
==
typeid(
float
));
assert (MaX((
float
)
2
, (__int64)
2
)
==
2
);
assert (std::
string
(
"
hello
"
)
<
"
world
"
);
assert (typeid(MaX(std::
string
(
"
hello
"
),
"
world
"
))
==
typeid(std::
string
));
assert (MaX(std::
string
(
"
hello
"
),
"
world
"
)
==
"
world
"
);
assert (typeid(MaX(std::
string
(
"
world
"
),
"
hello
"
))
==
typeid(std::
string
));
assert (MaX(std::
string
(
"
hello
"
),
"
world
"
)
==
"
world
"
);
//
测试数,需定义在循环外,防止编译器优化掉无意义的循环
__int64 test
=
0
;
long
start
=
GetTickCount();
for
(
int
i
=
0
; i
<
1000000000
;
++
i)
{
test
+=
MaX(i, (__int64)i);
}
//
test必须被使用,否则编译器视为无用数据,会被优化掉
std::cout
<<
test
<<
std::endl;
std::cout
<<
(GetTickCount()
-
start)
<<
std::endl;
test
=
0
;
start
=
GetTickCount();
for
(
int
i
=
0
; i
<
1000000000
;
++
i)
{
test
+=
max(i, (__int64)i);
}
std::cout
<<
test
<<
std::endl;
std::cout
<<
(GetTickCount()
-
start)
<<
std::endl;
return
0
;
}