2014-01-17 61 views
4

編寫單元測試時,我經常想用一組參數調用一個函數。例如,我有被聲明爲搜索參數空間時避免嵌套for-loops

void tester_func(int p1, double p2, std::string const& p3); 

功能和一些選定的參數

std::vector<int> vec_p1 = { 1, 2, 666 }; 
std::vector<double> vec_p2 = { 3.14159, 0.0001 }; 
std::vector<std::string> vec_p3 = { "Method_Smart", "Method_Silly" }; 

我目前做的只是爲

for(auto const& p1 : vec_p1) 
    for(auto const& p2 : vec_p2) 
     for(auto const& p3 : vec_p3) 
      tester_func(p1, p2, p3); 

然而,Sean Parent建議避免顯式循環並改用std::算法。在上述情況下,如何能夠遵循這個建議?任何成語?編寫可變參數模板的最簡潔的方法是什麼?什麼是最好的方法沒有C++ 11功能

+0

答案可能取決於它的單元測試框架您使用。 –

+0

提升UnitTest。 'tester_func'自動記錄所有錯誤。只有對所有參數組合調用該函數纔是重要的。 –

+0

在您鏈接的視頻中,他明確指出,只要循環體是單個語句/賦值,使用範圍for循環有時(節省打字時間)是可以的。我認爲你在這裏做的是好的。 –

回答

1

在@Oberon的評論中提到了非常好的解決方案。

但我認爲這個問題有很多不同的解決方案。這裏是我的解決方案:

#include <tuple> 
#include <type_traits> 

template <class TestFunction, class... Containers, class... Types> 
typename std::enable_if<sizeof...(Containers) == sizeof...(Types)>::type 
TestNextLevel 
    (
     TestFunction testFunction, 
     const std::tuple<Containers...>& containersTuple, 
     const Types&... parameters 
    ) 
{ 
    testFunction(parameters...); 
} 

template <class TestFunction, class... Containers, class... Types> 
typename std::enable_if<(sizeof...(Containers) > sizeof...(Types))>::type 
TestNextLevel 
    (
     TestFunction testFunction, 
     const std::tuple<Containers...>& containersTuple, 
     const Types&... parameters 
    ) 
{ 
    for (const auto& element : std::get<sizeof...(Types)>(containersTuple)) 
    { 
     TestNextLevel(testFunction, containersTuple, parameters..., element); 
    } 
} 

template <class TestFunction, class... Containers> 
void TestAllCases 
    (
     TestFunction testFunction, 
     const Containers&... containers 
    ) 
{ 
    TestNextLevel 
     (
      testFunction, 
      std::tuple<const Containers&...>(containers...) 
     ); 
} 

使用的實例:

TestAllCases(tester_func, vec_p1, vec_p2, vec_p3); 
+2

顯然,這比原代碼更容易理解:) – anonymous