使用braced-init-list打包扩展

时间:2016-12-29 05:44:44

标签: c++ c++11 c++14 variadic-functions

我决定自己用C ++实现Python的切片。我编写了一个函数,它接受可变参数slice_info<int>并返回n维数组的切片选择ndvalarray<T, D>

我使用Visual C ++ 2015编译,代码如下:

template<typename T>
struct slice_info {
    T fr, to, step;

    slice_info(T i) {
        fr = 1; to = i; step = 1;
    }

    slice_info(std::initializer_list<T> il) {
        std::vector<T> l(il);
        if (l.size() == 1)
        {
            fr = 1; step = 1; to = l[0];
        }
        else if (l.size() == 2) {
            fr = l[0]; step = 1; to = l[1];
        }
        else {
            fr = l[0]; step = l[2]; to = l[1];
        }
    }

    slice_info(const slice_info<T> & x) : fr(x.fr), to(x.to), step(x.step) {
    }
};

template<typename T, int D>
void slice(const ndvalarray<T, D> & va, slice_info<int>&& s) {
    // ndvalarray<T, D> is a n-dimensional array of type T
}

template<typename T, int D, typename ... Args>
void slice(const ndvalarray<T, D> & va, slice_info<int>&& s, Args&& ... args) {
    slice(va, std::forward<Args>(args)...);
}

template<typename T, int D>
void slice_work_around(const ndvalarray<T, D> & va, const std::vector<slice_info<int>> & vs) {

}
int main(){
    // Here is a 3-dimensional arr
    ndvalarray<int, 3> arr;
    // I want to get a slice copy of arr.
    // For dimension 1, I select elements from position 1 to position 2.
    // For dimension 2, I select elements from position 3 to position 6 stride 2
    // For dimension 3, I select only the position 7 element
    slice(arr, { 1, 2 }, { 3, 6, 2 }, {7}); // #1 error
    slice(arr, { 1, 2 }, slice_info<int>{ 3, 6, 2 }, slice_info<int>{7}); // #2 yes
    slice_work_around(arr, { {1, 2}, {3, 6, 2}, {7} }); // #3 yes
}

我认为#1是错误的,因为

  

braced-init-list不是表达式,因此没有类型

我尝试了#2和#3,他们工作了。但是我仍然想知道是否有可能使#1成为可能的方法。这个问题与c11-variable-number-of-arguments-same-specific-type有点类似,在我的例子中,这些可变数量的参数是braced-init-list。

slice_info<T>接受std::initializer_list<T>,以便描述维度的切片选择,例如std::slice()ndvalarray有多个维度,因此我必须提供一包slice_info<T>

我选择使用std::initializer_list<T>参数实现构造函数,因为我可以使用braced-init-list,而不需要给T或显式调用构造函数(比如#2)一样)。也许这是一个糟糕的设计,但我认为使用起来很简单。

0 个答案:

没有答案