初始化成员std::array的参数包

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

我有一堂课

Color
,它是围绕
std::array
的薄包装纸。 我希望能够以两种方式使用它:

  1. Color<5> color{1,2,3,4,5}
    应该产生
    color.values = [1,2,3,4,5]
  2. Color<5> color{3}
    应该产生
    color.values = [3,3,3,3,3]

我目前拥有的是:

template <size_t N>
class Color {
public:
    Color() = default;
    Color(std::array<float, N> values) : values{ values } {};

    template <IsNumeric... T>
    Color(T... v) : values{ static_cast<float>(v)... } { };

    ....
}

这对于我的第一种情况是正确的。 然而,对于第二种情况,它只会产生:

color.values = [3,0,0,0,0]
。 我不知道如何让第二个案例发挥作用。 我试过了:

template <size_t N>
class Color {
public:
    Color() = default;
    Color(std::array<float, N> values) : values{ values } {};

    template <IsNumeric... T, typename std::enable_if<(sizeof...(T) == N), bool>::type = true>
    Color(T... v) : values{ static_cast<float>(v)... } { };

    template <IsNumeric T>
    Color(T v) : values{ std::array<float, N>{ static_cast<float>(v) } } { };

    ...
}

但这并没有改变任何事情。

c++ templates initialization parameter-pack
1个回答
0
投票

您可以借助

std::index_sequence
和辅助函数来完成此操作。由于您已经在使用概念,因此应该使用
requires
子句来替换
std::enable_if

您尚未指定

values
是什么,我在这里使用
std::array
作为示例,但只要
values
的类型具有执行正确操作的可变参数构造函数,它就应该有效。

namespace detail{
    template <std::size_t... Is, typename T>
    constexpr std::array<float, sizeof...(Is)> makeValues(std::index_sequence<Is...>, T v){
        return {((void)Is, v)...};
    }
}

template <size_t N>
class Color {
public:
    constexpr Color() = default;
    //constexpr Color(std::array<float, N> values) : values{ values } {};

    template <IsNumeric... T> requires (sizeof...(T) == N)
    constexpr Color(T... v) : values{ static_cast<float>(v)... } { };

    template <IsNumeric T>
    constexpr Color(T v) : values{detail::makeValues(std::make_index_sequence<N>{}, static_cast<float>(v))} { };

    std::array<float, N> values;
};

可以通过以下测试主函数来验证:

int main(){
    static_assert(Color<2>{5,4}.values == std::array<float,2>{5,4});
    static_assert(Color<2>{5}.values == std::array<float,2>{5,5});
    // Color<3> doesntCompile{1,2};
}

演示:https://godbolt.org/z/MWx6416sx

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