调用每种类型的变异模板的正确模板专业化

Call right template specialization for each type of a variadic template

本文关键字:专业化 变异 种类 类型 调用      更新时间:2023-10-16

i具有一个函数 foo(),该函数列出了类型的 T...和内部调用另一个(模板(函数,称为 do_stuff(),称为向量的每个元素。向量(长度为 sizeof...(T)(,并且想致电do_stuff<Ti>(),其中 Tii'the T...

中的 CC_8'th类型

这些信息在编译时可用,所以我想这是可能的,但是我们如何做得很好?

#include <iostream>
#include <string>
#include <vector>
#include <cassert>
template <typename T>
T do_stuff(int param);
template <>
int do_stuff(int param)
{
    return int(100);
}
template <>
std::string do_stuff(int param)
{
    return std::string("foo");
}
template <typename... T>
void foo(const std::vector<int>& p)
{
    assert(p.size() == sizeof...(T));
    for (int i = 0; i < p.size(); ++i)
    {
        // Won't compile as T is not specified:
        //do_stuff(p[i]);
        // How do we choose the right T, in this case Ti from T...?
    }
}
int main()
{
    std::vector<int> params = { 0,1,0,5 };
    foo<int, std::string, std::string, int>(params);
}

您可以使用C 17倍的表达式:

template <typename... T>
void foo(const std::vector<int>& p)
{
    assert(p.size() == sizeof...(T));
    std::size_t i{};
    (do_stuff<T>(p[i++]), ...);
}

godbolt.org上的实时示例


另外,您可以避免使用std::index_sequence的可变i变量:

template <typename... T>
void foo(const std::vector<int>& p)
{
    assert(p.size() == sizeof...(T));
    [&p]<auto... Is>(std::index_sequence<Is...>)
    {
        (do_stuff<T>(p[Is]), ...);
    }(std::index_sequence_for<T...>{});
}

godbolt.org上的实时示例

如下何处?

template <typename ... T>
void foo (std::vector<int> const & p)
{
    assert(p.size() == sizeof...(T));
    using unused = int[];
    std::size_t  i{ 0u };
    (void)unused { 0, ((void)do_stuff<T>(p[i++]), 0)... };
}

如果您可以使用C 17,请参见Vittorio Romeo的答案,以获得更优雅和简洁的解决方案。