2013-04-08 91 views
3

假設我想用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

回答

6

Boost.MPL

這是可能的類型串完成 - 它們在細節Modern C++ Design: Generic Programming and Design Patterns Applied通過安德烈Alexandrescu的

檢查Boost.MPL庫討論。例如 - boost::mpl::for_each

LIVE DEMO

#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可變參數模板

另一種選擇是使用C++ 11個可變參數模板:

LIVE DEMO

#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()); 
} 
+0

BOOST.MPL對我來說絕對夠用,但是有一個問題可能會讓人感到興奮:它[不起作用](http://liveworkspace.org/code/2TZHbN$4)與非默認的可構造類型(如果我測試它正確) – RiaD 2013-04-08 01:13:12

+0

在這種情況下,快速解決方案只是[使用指針](http://liveworkspace.org/code/sChpB$0) – 2013-04-08 01:20:09

+0

這是否會導致向量元素的構造函數被調用? @EvgenyPanasyuk:你的鏈接不適合我。我想你是在談論同樣的問題,並建議使用指針類型來調用? – Syncopated 2015-02-13 03:17:39

0

我已經成功地做一些工作,但不是很漂亮,只用默認costructable類型的作品:

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()); 
} 
+0

檢查botton的[我的答案](http://stackoverflow.com/a/15869682/1762344) - 我有第二種方法基於可變模板 - 它不需要默認構造性 – 2013-04-08 01:21:27

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

+1

有可能做[無遞歸](http://liveworkspace.org/code/yOEFa$11):auto && t = {(do_test (),0)...}; – 2013-04-08 01:26:26

+0

@EvgenyPanasyuk很好! – mfontanini 2013-04-08 03:10:15