簡體   English   中英

使用非類型模板參數重復調用函數

[英]Repeatedly calling a function with a non-type template parameter

我有一個函數與int類型的非類型模板參數,如下所示:

template <int N>
int foo() { /*...*/ }

我想對N所有值從0到32進行單元測試。我有一個函數int expected(int n) ,它取相同的N值並返回期望的值。 實際上,我想:

if (foo<0>() != expected(0)) { /* fail... */ }
if (foo<1>() != expected(1)) { /* fail... */ }
if (foo<2>() != expected(2)) { /* fail... */ }
// 30 more lines

我不想手工寫出所有33個測試用例,我不能輕易使用運行時循環,因為N是編譯時間。

在C ++ 11中,如何在沒有BOOST_PP_REPEAT style技巧或代碼生成的情況下以簡單的方式讓編譯器為我生成測試用例?

您可以編寫具有完全特化的遞歸函數模板來執行測試。 例如

template <int N>
void test() {
    test<N-1>();
    if (foo<N>() != expected(N)) { /* fail... */ }
}

template <>
void test<-1>() {
    // do nothing
}

並運行它

test<32>();

在c ++ 14中,你可以做這樣的事情

#include <type_traits>

template <int beg, int end> struct static_for {
    template <typename Fn> void operator()(Fn const& fn) const {
        if (beg < end) {
            fn(std::integral_constant<int, beg>());
            static_for<beg + 1, end>()(fn);
        }
    }
};

template <int n> struct static_for<n, n> {
    template <typename Fn> void operator()(Fn const& fn) const {}
};

template <int N> int foo() { /*...*/
    return N;
}

int main() {
    static_for<0, 32>()([&](auto i) {
        if (foo<i>() != i) { /* fail... */
        }
    });
    return 0;
}

這是一個方法:

template<int N>
void f();

template<int... N>
void g(std::index_sequence<N...>)
{
  (f<N>(), ...);
}

可以像這樣調用:

g(std::make_index_sequence<33>());

編輯:

這是實際檢查測試是否成功完成的版本:

template<int N>
int f();

int expected(int n);

template<int... N>
bool g(std::index_sequence<N...>)
{
  return ((f<N>() == expected(N)) && ...);
}

使用如下:

g(std::make_index_sequence<33>()); // true if all tests are sucessful, false otherwise

一種可能的C ++ 14解決方案,它“模擬”C ++ 17模板折疊並在第一次失敗時中斷f<N> != expected(N)

template <int N>
void f ();

template <int ... Is>
void g (std::integer_sequence<int, Is...>)
 {
   using unused = int[];

   bool ret { false };

   (void)unused { 0, (ret ? 0 : (ret = (f<Is>() != expected(Is)), 0))... }; 
 }

可調用如下

g(std::make_integer_sequence<33>());

對於C ++ 11解決方案,您需要替換僅在C ++ 14中可用的std::make_integer_sequence / std::integer_sequence

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM