【问题标题】:How to pass a row of boost::multi_array and std::vector by reference to the same template function?如何通过引用同一个模板函数来传递一行 boost::multi_array 和 std::vector?
【发布时间】:2010-01-24 22:46:25
【问题描述】:

我对这段代码有疑问:

#include <boost/multi_array.hpp>
#include <boost/array.hpp>
#include <vector>
#include <iostream>

template <typename Vec>
void foo(Vec& x, size_t N)
{
    for (size_t i = 0; i < N; ++i) {
        x[i] = i;
    }
}

int main()
{
    std::vector<double> v1(10);
    foo(v1, 5);
    std::cout << v1[4] << std::endl;


    boost::multi_array<double, 2> m1;
    boost::array<double, 2> shape;
    shape[0] = 10;
    shape[1] = 10;
    m1.resize(shape);
    foo(m1[0], 5);
    std::cout << m1[0][4] << std::endl;
    return 0;
}

尝试用 gcc 编译它,我得到了错误:

boost_multi_array.cpp: In function 'int main()':
boost_multi_array.cpp:26: error: invalid initialization of non-const reference of type 'boost::detail::multi_array::sub_array<double, 1u>&' from a temporary of type 'boost::detail::multi_array::sub_array<double, 1u>'
boost_multi_array.cpp:7: error: in passing argument 1 of 'void foo(Vec&, size_t) [with Vec = boost::detail::multi_array::sub_array<double, 1u>]'

当我将函数foo 的第一个参数的类型从Vec&amp; 更改为Vec 时,它对 boost::multi_array 的工作正常,但随后 std::vector 是按值传递的,这不是我想要的是。不编写两个模板如何实现我的目标?

【问题讨论】:

    标签: c++ templates boost boost-multi-array


    【解决方案1】:

    问题在于,对于 NumDims > 1operator[] 返回一个 template subarray&lt;NumDims-1&gt;::type 类型的临时对象。

    一个(不太好的)解决方法如下:

    typedef boost::multi_array<double, 2> MA;
    MA m1;
    MA::reference ref = m1[0];
    foo(ref, 5); // ref is no temporary now
    

    另一种方法是包装您的实现并为多数组情况提供重载......例如:

    (注意:我没有看到如何让重载与 boost::multi_array&lt;T,N&gt;::reference 一起使用,请不要将其与此 detail:: 版本一起投入生产使用;)

    template<class T>
    void foo_impl(T x, size_t N) {
        for (size_t i = 0; i < N; ++i) {
            x[i] = i;
        }
    }
    
    template<class T>
    void foo(T& t, size_t n) {
        foo_impl<T&>(t, n);
    }
    
    template<typename T, size_t size>
    void foo(boost::detail::multi_array::sub_array<T, size> r, size_t n) {
        foo_impl(r, n);
    }
    

    【讨论】:

    • 能否使用 boost::enable_if_c 和 boost::traits 优雅地解决这个问题?
    • MA::reference ref = m1[0] 行在语法上肯定没有那么简洁,但它不会在运行时为 std::vector 情况增加大量开销。我最近遇到了同样的问题:old.nabble.com/…
    • @quant_dev: 还有一个问题是为什么直接使用boost::multi_array&lt;T,N&gt;::reference 不起作用,我没有时间进一步调查。
    猜你喜欢
    • 1970-01-01
    • 2018-10-18
    • 2013-07-27
    • 2019-05-10
    • 1970-01-01
    • 2012-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多