在下面的代码中,我定义了一个名为unsigned int
的{{1}},我用它来打印类型本身的最大值:
my_type
如何在不重复此代码的情况下对多种类型执行相同的操作?
我尝试创建一个存储类型#include <iostream>
#include <limits>
#include <cmath>
...
using namespace std;
int main() {
typedef unsigned int my_type;
const my_type max_int = numeric_limits<my_type>::max():
cout << max_int << endl;
return 0;
}
和unsigned int
的字符串数组(作为示例),但这不起作用:
long
我也尝试过使用模板,但无法弄清楚如何操作。
这甚至可能吗?
答案 0 :(得分:5)
#include <iostream>
#include <limits>
using namespace std;
template <typename T>
void printMax()
{
cout << numeric_limits<T>::max() << endl;
}
int main()
{
printMax<unsigned int>();
printMax<double>();
return 0;
}
和
$ g++ test.cpp && ./a.out
4294967295
1.79769e+308
答案 1 :(得分:2)
C ++没有反射,因此您无法将c ++字符串转换为类型名称。但是您可以为任务使用可变参数模板。
#include <iostream>
#include <limits>
#include <cmath>
using namespace std;
template <typename ... Args>
struct TL;
template <typename T>
struct TL<T>
{
static void print()
{
const T max_int = numeric_limits<T>::max();
cout << max_int << endl;
}
};
template <typename T, typename ... Args>
struct TL<T, Args...>
{
static void print()
{
TL<T>::print();
TL<Args...>::print();
}
};
int main(int , char** )
{
TL<int, unsigned int, short int>::print();
return 0;
}
<强>更新强>
更复杂的例子。
您可以为保留类型列表声明可变参数模板:
template <typename ... Args>
struct TypeList;
template <typename T>
struct TypeList<T>
{
typedef T type;
};
template <typename T, typename ... Args>
struct TypeList<T, Args...>
{
typedef T type;
// typedef TypeList<Args...> rest;
};
和执行操作的模板,取决于类型列表中每个元素的类型:
template <typename L, template <typename T> class Op>
struct ForEach;
template <typename T, template <typename T> class Op>
struct ForEach<TypeList<T>, Op>
{
void operator()()
{
Op<T>()();
}
};
template <typename T, template <typename T> class Op, typename ... Args>
struct ForEach<TypeList<T, Args...>, Op>
{
void operator()()
{
Op<T>()();
ForEach<TypeList<Args...> , Op>()();
}
};
现在,您可以使用operator()
声明一些函数,如模板化结构#include <iostream>
#include <limits>
#include <cmath>
using namespace std;
template <typename T>
struct PrintNumericTypeMaxLimit
{
void operator()()
{
const T max_int = numeric_limits<T>::max();
cout << max_int << endl;
}
};
template <typename T>
struct PrintNumericTypeMinLimit
{
void operator()()
{
const T min = numeric_limits<T>::min();
cout << min << endl;
}
};
并将其与您的类型列表一起使用:
int main(int , char** )
{
typedef TypeList<int, unsigned int, long int, short int, unsigned short int, double> myList;
ForEach<myList, PrintNumericTypeMaxLimit>()();
ForEach<myList, PrintNumericTypeMinLimit>()();
return 0;
}
答案 2 :(得分:2)
您可以使用boost::variant
通知所需的类型,boost::mpl::foreach
循环播放它们
和一个以pre-c ++ 11方式或使用c ++ 11 lambda
#include <iostream>
#include <limits>
#include <boost/variant.hpp>
#include <boost/mpl/for_each.hpp>
struct printMaxNumLimits
{
template<class Type>
void operator()(Type t) {
std::cout << std::numeric_limits<Type>::max() << std::endl;
}
};
int main()
{
using variant_types = boost::variant<int, double, unsigned int>;
// pre c++11
boost::mpl::for_each<variant_types::types>(printMaxNumLimits());
// c++11
boost::mpl::for_each<variant_types::types>([](auto t){
std::cout << std::numeric_limits<decltype(t)>::max() << std::endl;
});
}