[英]Compile time creation of class member stl container (const std::array) filled with elements
I tried to create a minimal example as it is possible with templates. 我尝试创建一个最小的示例,因为它可以使用模板。
(MSVC15, c++14) (MSVC15,c ++ 14)
There are 2 questions may be connected with each other. 有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>;
#include <iostream>
#include <memory>
#include <array>
template<class T, size_t MaxIndex>
class BaseIndex
{
public:
virtual ~BaseIndex() = default;
explicit BaseIndex(const size_t index)
: _maxIndex(MaxIndex), _currentIndex(index) {}
virtual void DoSmth() = 0;
friend std::ostream & operator << (std::ostream & ss, BaseIndex & base_index)
{
ss << "Max: " << base_index._maxIndex << ". Current: " << base_index._currentIndex << std::endl;
return ss;
}
protected:
const size_t _maxIndex;
size_t _currentIndex{ 0u };
};
template<size_t MaxIndex>
class IndexStr : public BaseIndex<std::string, MaxIndex>
{
public:
explicit IndexStr(const size_t index) :BaseIndex(index) {}
void DoSmth() override { std::cout << IndexStr::_maxIndex; }
};
template<size_t MaxIndex>
class IndexInt :public BaseIndex<int, MaxIndex>
{
public:
explicit IndexInt(const size_t index) :BaseIndex(index) {}
void DoSmth() override { std::cout << IndexInt::_maxIndex; }
};
class Manager
{
private:
static const size_t _startStrIndex{ 11u };
static const size_t _startIntIndex{ 10060u };
static const size_t _maxStrIndexes{ 5 };
static const size_t _maxIntIndexes{ 120 };
public:
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>;
// const std::array<std::shared_ptr<IndexStr<_maxStrIndexes>>, _maxStrIndexes> _strIndexes
_limited_str_ptr_container _strIndexes
{
// _startStrIndex
// create indexes ???
// std::integer_sequence ???
std::make_shared<_limited_str_>(_startStrIndex), // 11 = _startStrIndex
std::make_shared<_limited_str_>(12),
std::make_shared<_limited_str_>(13),
std::make_shared<_limited_str_>(14),
std::make_shared<_limited_str_>(_startStrIndex + _maxStrIndexes - 1)
};
// is it possible to combine this 2 types and use _maxIntIndexes only once?
using _limited_int_ = IndexInt<_maxIntIndexes>;
using _limited_int_ptr = _ptr<_limited_int_>;
using _limited_int_ptr_container = _container<_limited_int_ptr, _maxIntIndexes>;
_limited_int_ptr_container _intIndexes
{
// _startIntIndex
// create indexes???
std::make_shared<_limited_int_>(_startIntIndex), // 10060u _startStrIndex
//...
std::make_shared<_limited_int_>(_startIntIndex + _maxIntIndexes -1)
};
};
template <class T, size_t Size >
void Process(const std::array<std::shared_ptr<T>, Size> _array)
{
for (auto &&baseindex : _array)
std::cout << *baseindex;
}
int main()
{
Manager m;
Process(m._strIndexes);
//Process(m._intIndexes);
return 0;
}
About the first question : yes, it is possible. 关于第一个问题 :是的,有可能。 It is even quite easy provided that you can use C++11 and variadic templates. 只要您可以使用C ++ 11和可变参数模板,它就非常容易。
To generate a compile-time list of indices, you can use std::make_index_sequence<N>
, which will return a std::index_sequence<0, 1, 2, 3, ..., N-1>
. 要生成索引的编译时列表,可以使用std::make_index_sequence<N>
,它将返回std::index_sequence<0, 1, 2, 3, ..., N-1>
。 You can then pattern-match it with the function creating the compile-time array: 然后可以将其与创建编译时数组的函数进行模式匹配:
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>());
}
If you want to add an offset to the index_sequence
members, just do so in the array initialization: 如果要向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)... };
}
About the second question: As far as I understand it, yes, it's possible. 关于第二个问题:据我了解,是的,有可能。 First, create a helper struct
to query the index of _limited_str
: 首先,创建一个辅助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;
};
Then, rather than refering to _maxStrIndexes
directly, you can query it from indirectly from _limited_str_ptr
: 然后,您可以直接从_limited_str_ptr
间接查询_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>;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.