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

Partial template argument deduction or workaround for std::array?

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':模板参数太少

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

据我所知,这是做不到的。但是辅助方法可以解决问题:

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);

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

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 );

在 "here" 上,使用最新的 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 });

享受...