类成员stl容器(const std :: array)的编译时创建,其中填充了元素

时间:2018-11-21 12:25:44

标签: c++ c++11 templates stl initializer-list

我尝试创建一个最小的示例,因为使用模板是可能的。

(MSVC15,c ++ 14)

可能有2个相互关联的问题。

问题1:是否可以在编译时创建充满元素的容器类成员(例如std :: array)?

0:  ["M", 0, 0]
1:  ["H", 50]
2:  ["A", 20, 20, 0, 1, 0, 100, 50]
3:  ["V", 75]
4:  ["C", 50, 125, 0, 85, 0, 85]

问题2:是否可以将多个模板类与一个通用模板参数组合而只能组合一次?

    _limited_int_ptr_container _intIndexes
    {
        // _startIntIndex
        // create indexes???
        std::make_shared<_limited_int_>(_startIntIndex), // 10060u  _startStrIndex
        //std::make_shared<_limited_int_>(_startIntIndex + 1),
        //std::make_shared<_limited_int_>(_startIntIndex + 2),
        //...
        std::make_shared<_limited_int_>(_startIntIndex + _maxIntIndexes -1)
    };

完整代码:

    template <class T, size_t Size>
    using _container = const std::array<T, Size>;

    template <class T>
    using _ptr = std::shared_ptr<T>;

    // is it possible to combine this 2 types and use _maxStrIndexes only once?
    using _limited_str_ = IndexStr<_maxStrIndexes>;
    using _limited_str_ptr = _ptr<_limited_str_>;
    using _limited_str_ptr_container = _container<_limited_str_ptr, _maxStrIndexes>;

Live demo

1 个答案:

答案 0 :(得分:3)

关于第一个问题:是的,有可能。只要您可以使用C ++ 11和可变参数模板,就非常容易。

要生成索引的编译时列表,可以使用std::make_index_sequence<N>,它将返回std::index_sequence<0, 1, 2, 3, ..., N-1>。然后可以使用创建编译时数组的函数对其进行模式匹配:

template <std::size_t... Ns>
constexpr auto fill_it_at_compile_time_impl(std::index_sequence<Ns...>) {
    return std::array<unsigned, sizeof...(Ns)>{ Ns... };
}

template <std::size_t N>
constexpr auto fill_it_at_compile_time() {
    return fill_it_at_compile_time_impl(std::make_index_sequence<N>());
}

如果要向index_sequence成员添加偏移量,只需在数组初始化中这样做:

constexpr auto offset = 10u;
template <std::size_t... Ns>
constexpr auto fill_it_at_compile_time_impl(std::index_sequence<Ns...>) {
    return std::array<unsigned, sizeof...(Ns)>{ (offset+Ns)... };
}

关于第二个问题: 据我了解,是的,有可能。首先,创建一个助手struct来查询_limited_str的索引:

template <typename T>
struct query_max_index; 
template <std::size_t N>
struct query_max_index<IndexStr<N>> {
    static const auto max_index = N;
};

然后,您可以直接从_maxStrIndexes间接查询_limited_str_ptr,而不是直接查询using _limited_str_ = IndexStr<_maxStrIndexes>; using _limited_str_ptr = _ptr<_limited_str_>; using _limited_str_ptr_container = _container<_limited_str_ptr, query_max_index<std::decay_t<decltype(*std::declval<_limited_str_ptr>())>>::max_index>;

CORE_LOGGING_LEVEL=debug