2013-04-08 4 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

typelists으로 수행 할 수 있습니다 - 그들은 안드레이 Alexandrescu의

확인 Boost.MPL 라이브러리 Modern C++ Design: Generic Programming and Design Patterns Applied에서 세부 사항을 논의한다. 예를 들어 - 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) 가변 인자 템플릿을 사용하는 것입니다 :

,451,515,

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()); 
} 
I 작동 뭔가를 관리하지만, 매우 아름다운하지 않고 기본 - costructable 유형에서만 작동 한
+0

BOOST.MPL은 나를 위해 절대적으로 충분하지만, intresting 일 수있는 1 가지 문제가 있습니다. 기본 구성 가능 유형이 아닌 [작동하지 않음] (http://liveworkspace.org/code/2TZHbN$4) (테스트하는 경우) – RiaD

+0

그런 경우 빠른 해결책은 [포인터 사용] (http://liveworkspace.org/code/sChpB$0) –

+0

입니다. 그러면 벡터 요소의 생성자가 호출됩니까? @ EvgenyPanasyuk : 귀하의 링크가 나를 위해 작동하지 않습니다. 나는 당신이 같은 문제에 대해 이야기하고 있다고 가정하고 대신에 포인터 타입으로 호출을 제안 했는가? – Syncopated

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

[내 대답]의 botton 확인 (http://stackoverflow.com/a/15869682/1762344) - 난 variadic 템플릿을 기반으로 두 번째 접근 방식을 가지고 - 그것은 기본적으로 constructive 필요하지 않습니다 –

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) : 자동 && t = {(do_test (), 0) ...}; –

+0

@EvgenyPanasyuk nice! – mfontanini