CSDN上看到有人問能否實(shí)現(xiàn)一個(gè)效率較高的max函數(shù),效率接近于宏,于是自動(dòng)動(dòng)手寫了一個(gè)。
由于max宏在判斷不同類型時(shí),能夠返回大的那個(gè)類型(表示范圍大),所以只能使用模板來進(jìn)行返回類型的推導(dǎo)。
在VC8上打開O2或Ox優(yōu)化選項(xiàng),測試結(jié)果是與宏效率相等。
全部實(shí)現(xiàn)如下:
由于max宏在判斷不同類型時(shí),能夠返回大的那個(gè)類型(表示范圍大),所以只能使用模板來進(jìn)行返回類型的推導(dǎo)。
在VC8上打開O2或Ox優(yōu)化選項(xiàng),測試結(jié)果是與宏效率相等。
全部實(shí)現(xiàn)如下:
#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");
// 測試數(shù),需定義在循環(huán)外,防止編譯器優(yōu)化掉無意義的循環(huán)
__int64 test = 0;
long start = GetTickCount();
for (int i=0; i<1000000000; ++i)
{
test += MaX(i, (__int64)i);
}
// test必須被使用,否則編譯器視為無用數(shù)據(jù),會(huì)被優(yōu)化掉
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;
}
#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");
// 測試數(shù),需定義在循環(huán)外,防止編譯器優(yōu)化掉無意義的循環(huán)
__int64 test = 0;
long start = GetTickCount();
for (int i=0; i<1000000000; ++i)
{
test += MaX(i, (__int64)i);
}
// test必須被使用,否則編譯器視為無用數(shù)據(jù),會(huì)被優(yōu)化掉
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;
}