我尝试为轻量级数组类实现std::initializer_list
构造函数,但后来我立即发现std::initializer_list
为constexpr
的问题。我通过使用可变参数模板构造函数和辅助函数以某种方式解决了它,但感觉就像这个单一目的的过度杀伤(IMO)。我对C ++的经验很短,所以我相信有更好更简单的方法。
我还考虑过从std::array
使用移动构造函数?但移动表达的概念对我来说仍然不清楚。无论如何,这还值得考虑吗?
任何好的解决方案或建议都会对我有帮助。
template<typename T>
class Array:private boost::scoped_array<T>{
private:
int m_length;
int CountArguments(){
return 0;
}
template<typename... Ts>
int CountArguments(T const& t,Ts const&... ts){
return 1+CountArguments(ts...);
}
void FillFromArguments(T* p){}
template<typename... Ts>
void FillFromArguments(T* p,T const& t,Ts const&... ts){
*p++=t;
FillFromArguments(p,ts...);
}
public:
Array(){}
Array(int length):
boost::scoped_array<T>(new T[length]),
m_length(length){}
template<typename... Ts>
Array(T const& t,Ts const&... ts){
m_length=CountArguments(t,ts...);
boost::scoped_array<T>::reset(new T[m_length]);
FillFromArguments(boost::scoped_array<T>::get(),t,ts...);
}
/* ... */
};
答案 0 :(得分:0)
与问题评论一样,我没有看到std::initializer_list
的问题。但你绝对不需要你写的任何成员函数。我们可以在构造函数中构造完整的数组:
template <typename... Ts,
typename = std::enable_if_t<
all_true<std::is_constructible<T, Ts&&>::value...>::value
>>
Array(Ts&&... ts)
: boost::scoped_array<T>{new T[sizeof...(Ts)]{
std::forward<Ts>(ts)...
}}
, length(sizeof...(Ts))
{
}
all_true
来自Columbo here。这具有使用非默认可构造类型的额外好处:
struct X {
X(int ) { }
};
int main() {
Array<X> t(1, 2, 3); // OK
}
虽然更简单的解决方案只是:
template <typename T>
class Array : private std::vector<T>
{
public:
// constructor
using std::vector<T>::vector;
// accessors
using std::vector<T>::size;
using std::vector<T>::begin;
using std::vector<T>::end;
using std::vector<T>::operator[];
// other functions that don't include push_back(), erase(), emplace(), ...
};
让标准库处理所有事情。