假设我想要使用vector<int>
,vector<bool>
,vector<string>
进行测试。我想写这样的东西:
for(type T in {int, bool, string}){
vector<T> v;
for(int i = 0; i < 3; ++i){
v.push_back(randomValue<T>());
}
assert(v.size() == 3);
}
我知道语言中没有这样的功能,但有可能以某种方式模仿吗?在某些库中是否存在此功能,例如boost
?
答案 0 :(得分:6)
可以使用类型列表来完成 - Modern C++ Design: Generic Programming and Design Patterns Applied详细讨论了 Andrei Alexandrescu
检查Boost.MPL库。例如 - boost::mpl::for_each
#include <boost/exception/detail/type_info.hpp>
#include <boost/mpl/for_each.hpp>
#include <boost/mpl/vector.hpp>
#include <iostream>
#include <cassert>
#include <vector>
#include <string>
using namespace boost;
using namespace std;
template<typename T>
T randomValue()
{
return T();
}
struct Benchmark
{
template<typename T>
void operator()(T) const
{
cout << "Testing " << type_name<T>() << endl;
vector<T> v;
for(int i = 0; i < 3; ++i)
{
v.push_back(randomValue<T>());
}
assert(v.size() == 3);
}
};
int main()
{
mpl::for_each<mpl::vector<int, bool, string>>(Benchmark());
}
输出是:
Testing int
Testing bool
Testing std::string
另一种选择是使用C ++ 11可变参数模板:
#include <boost/exception/detail/type_info.hpp>
#include <iostream>
#include <cassert>
#include <vector>
#include <string>
using namespace boost;
using namespace std;
template<typename T>
T randomValue()
{
return T();
}
struct Benchmark
{
template<typename T>
void operator()(T) const
{
cout << "Testing " << type_name<T>() << endl;
vector<T> v;
for(int i = 0; i < 3; ++i)
{
v.push_back(randomValue<T>());
}
assert(v.size() == 3);
}
};
template<typename ...Ts,typename F>
void for_each(F f)
{
auto &&t = {(f(Ts()),0)...};
(void)t;
}
int main()
{
for_each<int, bool, string>(Benchmark());
}
答案 1 :(得分:1)
这使用可变参数模板来实现:
template<typename T>
void do_test(){
// do the actual testing here, for type T
}
template<typename T>
void test_vectors() {
do_test<T>();
}
template<typename T, typename Head, typename... Tail>
void test_vectors() {
do_test<T>();
test_vectors<Head, Tail...>();
}
演示here。
答案 2 :(得分:0)
我设法做了一些有效的事情,但不是很漂亮,只适用于默认的可构建类型:
void loop() {
}
template<typename T, typename... Args>
void loop(T t, Args... args) {
cerr << "work with " << typeid(T).name() << endl;
loop(args...);
}
int main() {
loop(int(), char(), vector<int>(), string());
}