c++ - 如何实现非 constexpr `std::initializer_list` 样式构造函数

标签 c++ templates c++11 constructor initializer-list

我试图为我的轻量级数组类实现一个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...);
    }

    /* ... */

};

最佳答案

关于问题的评论,我没有看到 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(), ...    
};

让标准库处理一切。

关于c++ - 如何实现非 constexpr `std::initializer_list` 样式构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30425538/

相关文章:

c++ - 通过 gcc-6 在 OSX Sierra 上安装时,保持 "FATAL:/opt/local/bin/../libexec/as/x86_64/as: I don' t 理解 'm' 标志!”错误

c++ - SFINAE:检测是否存在需要显式专门化的模板函数

c++ - 函数模板的显式实例化何时发生实例化

c++ - 是否可以概括一个将 STL 容器作为参数的函数?

c++ - 将大型成员对象移出类?

C++11并行实现

c++ - 从数组中检索值并保存在临时变量中是否比仅访问数组更快?

c++ - 显式移动构造函数是否消除了隐式复制构造函数?

c++ - 在 map 中使用 unique_ptr 时删除 std::pair 中的函数

c++ - 为什么 lambda 只捕获自动存储变量?