Reputation: 47619
Suppose I want test something with vector<int>
, vector<bool>
, vector<string>
. I want to write something like this:
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);
}
I know there isn't such feature in the language but is it possible to emulate somehow? Is there this functional in some library, for example boost
?
Upvotes: 3
Views: 162
Reputation: 9199
It is possible to accomplish with typelists - they are discussed in details in Modern C++ Design: Generic Programming and Design Patterns Applied by Andrei Alexandrescu
Check Boost.MPL library. For instance - 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());
}
Output is:
Testing int
Testing bool
Testing std::string
Another option is to use C++11 variadic templates:
#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());
}
Upvotes: 6
Reputation: 21900
This uses variadic templates to achieve that:
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...>();
}
Demo here.
Upvotes: 1
Reputation: 47619
I've managed to do something that works, but isn't very beautiful and works only with default-costructable types:
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());
}
Upvotes: 0