繁体   English   中英

在块 scope 重复使用非类型模板参数

[英]Repeatedly using non-type template parameter at block scope

我有以下代码片段:

template <size_t N>
foo make() { ... }

...

for (...) {
    auto foo = make<1>();
    // lots of tests involving foo
}

我想用非类型模板参数的不同值重复后一个块make ,例如make<2>make<3>等。

如果这是我想要迭代的类型,我可以使用这个解决方案,但不清楚我是否可以以相同的方式将非类型模板参数与通用 lambda 一起使用。

我怎样才能考虑到这一点,以便我可以创建运行上面的代码块,但使用不同的非类型参数值来实例化make 该解决方案应该只使用块范围元素 - 如果我可以创建一些顶级template <size_t N> struct maker {... } object 来包装make ,这很容易。

在这种情况下,正确的工具是使用std::integer_sequence

#include <iostream>
#include <utility>

template <size_t N>
void make()
{
  std::cout << N << std::endl;
}

template <size_t... I>
void do_make_helper(std::index_sequence<I...>)
{
  (make<I+1>(), ...); 
}

template <std::size_t N>
void do_make()
{
  do_make_helper(std::make_index_sequence<N>());
}

int main()
{
  do_make<10>();
}

印刷

1
2
3
4
5
6
7
8
9
10

作为手工索引列表的起点:

template <size_t N> int make();

template<> int make<1>() { std::cout<< "First" << std::endl; return 100; }
template<> int make<2>() { std::cout << "Second" << std::endl; return 200; }
template<> int make<3>() { std::cout << "Third" << std::endl; return 100; }

struct ExecuteInOrder { ExecuteInOrder( ... ) {} };

template < typename T>
void CallTest(T t )
{
    std::cout << "Your test code goes here...: " << t << std::endl;
}

    template< size_t ... N >
void Do()
{
    ExecuteInOrder {(CallTest(make<N>()),1)...};
}

int main()
{
    Do<1,2,3>();
}

或者您可以简单地使其递归并使用 index first and last 像这样:

template < size_t FIRST, size_t LAST >
void ExecuteAndTest()
{
    auto foo = make<FIRST>();
    std::cout << "Here we go with the test" << foo << std::endl;

    // go for next step
    if constexpr ( LAST != FIRST ) { ExecuteAndTest<FIRST+1, LAST>(); }
}

int main()
{
    // first and last index of integer sequence
    ExecuteAndTest<1,3>();
}

最后总是从 1 到 N

    template < size_t FIRST, size_t LAST >
void ExecuteAndTest_Impl()
{   
    auto foo = make<FIRST>();
    std::cout << "Here we go with the test" << foo << std::endl;

    // go for next step
    if constexpr ( LAST!= FIRST) { ExecuteAndTest_Impl<FIRST+1, LAST>(); }
}

    template < size_t LAST > 
void ExecuteAndTest()
{   
    ExecuteAndTest_Impl<1,LAST>();
}   

int main()
{   
    // or always start with 1 to n inclusive
    ExecuteAndTest<3>();
}  

你可以试试这个:

#include <utility>
#include <cassert>

struct Foo
{ 
    Foo() {}
    Foo(std::size_t i) : i(i) {}
    std::size_t i;
};

template <std::size_t... Is>
void setFoo(std::size_t i, Foo& foo, std::index_sequence<Is...>)
{
    ((i == Is && (foo = Foo{Is}, false)), ...);
}

int main()
{
    for (std::size_t i = 0; i < 10; i++)
    {
        Foo foo;
        setFoo(i, foo, std::make_index_sequence<10>{});
        assert(foo.i == i);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM