部分模板参数推导或std :: array的解决方法?

时间:2019-01-10 09:26:21

标签: c++ templates c++17 stdarray

C ++ 17允许我们推论std::array的模板参数。例如,我可以写

std::array ints = { 1, 2, 3 };

ints的类型为std::array<int, 3>

我的问题是:如果我只想指定数组的类型参数却又自动确定数组的大小怎么办?

以下内容不起作用,因为似乎必须指定所有模板参数:

std::array<size_t> sizes = { 1, 2, 3 };

我的编译器抱怨说:'std :: array':模板参数太少

是否可以通过模板参数推导自动确定数组的大小?如果没有,是否可以仅指定类型而不指定大小来创建数组?

2 个答案:

答案 0 :(得分:6)

据我所知,这是无法完成的。但是辅助方法可以解决问题:

template<typename Type, typename ... T>
constexpr auto makeArray(T&&... t) -> std::array<Type, sizeof...(T)>
{
    return {{std::forward<T>(t)...}};
}

用法示例:

const auto container = makeArray<double>(-5.0, 0.0, 5.0, 10.0);

答案 1 :(得分:0)

如果这样,我可能会大胆地扩大本杰明的答案。从概念上讲,不需要总是明确说明结果类型。

template<
typename ... T,
typename CT = std::common_type_t< T... >
>
constexpr auto make_array(T&& ... t)
 -> std::array<  CT , sizeof...(T)>
{
    return { { static_cast<CT>( std::forward<T>(t) ) ...} };
}

用法稍微简单

constexpr auto std_arr = make_array(-5.0, 0.0, 5.0, 10.0);

这里的问题可能是,我们不确定,我们将获得哪种类型的std::array。只要我们关心它。

const auto std_arr = make_array(-5.0, 0, 5.0, 10.0, 42.13f );

在“这里”,使用最新的MSVC,我得到了双精度标准数组。如果一个人的卧床时间阅读是ISO C ++标准文档,则可以确定使用的工具链中的std::common_type是哪种类型。

对于我们其他人,文字后缀会有所帮助

  constexpr auto sizes = make_array( 1UL, 2UL, 3UL );

但是为什么停在数字后面呢?可以将同一层次结构中的实例快速收集到阵列中。不关心结果类型。

    {
        const auto exceptions = make_array(
         std::exception{"SE"}, 
         std::runtime_error{"RE"}, 
         std::logic_error{"LE"} );
    }

有点没用,但是有点奇怪和美妙。您要记住的一件事:这是编译时的情况。因此,我可能更喜欢:

   constexpr auto sizes = std::array{ 1UL, 2UL, 3UL } ;

直接回答OP的问题。

There is also C ++ 20 std::to_array。对于确切的结果类型和更舒适的用法:

  constexpr auto sizes = std::to_array<size_t>({ 0, 1, 3 });

享受...