模板替换时访问参数包中的索引

问题描述 投票:0回答:1

我在 C++17 中有一个模板函数,其中 N 个第一个参数需要是整型,并且应该在模板替换期间检查这一点。 (对于不满足条件的参数,模板函数不应该存在,因此函数体中的

static_assert()
不起作用。)

它是类的构造函数,因此 SFINAE 是在模板参数中完成的。

对于固定 N = 2,这有效:

struct A {
    template<class Arg1, class Arg2, class... OtherArgs,
        std::enable_if_t<(std::is_integral_v<Arg1> && std::is_integral_v<Arg2>), int> = 0
    >
    A(Arg1 arg1, Arg2 arg2, OtherArgs... otherArgs)
};

然而,当

N
是模板参数时,似乎没有明显的方法。

要检查所有参数是否是整数,这有效:

template<std::size_t N>
struct A {
    template<class... Args,
        std::enable_if_t<std::conjunction_v<std::is_integral<Args>...>, int> = 0
    >
    A(Args... args)
};

有没有像

INDEX_OF
这样的工具,可以获取参数包中参数的索引,这样
is_integral
只需要对前N个参数为真?

template<std::size_t N>
struct A {
    template<class... Args,
        std::enable_if_t<std::conjunction_v<
            std::disjunction<
                std::bool_constant< (INDEX_OF(Args) >= N) >,
                std::is_integral<Args>
            >...
        >, int> = 0
    >
    A(Args... args)
};
c++ templates c++17 sfinae parameter-pack
1个回答
0
投票

您可以创建 constexpr 函数:

template <std::size_t N, typename... Ts>
static constexpr bool first_are_integral()
{
    constexpr bool bools[] = {std::is_integral_v<Ts>...};
    return std::all_of(std::begin(bools), std::begin(bools) + N,
                       [](bool b){ return b; });
}

然后

template <class... Args,
          std::enable_if_t<first_are_integral<N, Args...>(), int> = 0
>
A(Args...){ /*...*/ }

演示

© www.soinside.com 2019 - 2024. All rights reserved.