2010-01-24 22 views
5

Tôi có một vấn đề với chút mã này:Làm thế nào để vượt qua một hàng tăng :: multi_array và std :: vector bằng cách tham chiếu đến cùng một chức năng mẫu?

#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; 
} 

Đang cố gắng để biên dịch nó với gcc, tôi nhận được lỗi:

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>]' 

Nó hoạt động như mong đợi cho boost :: multi_array khi tôi thay đổi loại đối số đầu tiên của hàm foo từ Vec& đến Vec, nhưng sau đó vector std :: được truyền theo giá trị, không phải là thứ tôi muốn. Làm cách nào để đạt được mục tiêu của mình mà không cần viết hai mẫu?

Trả lời

1

Vấn đề là đối với NumDims> 1, operator[] trả về đối tượng tạm thời loại template subarray<NumDims-1>::type.

A (không quá đẹp) công việc xung quanh sẽ là một cái gì đó như sau:

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

Một thay thế sẽ được quấn thực hiện của bạn và cung cấp một tình trạng quá tải đối với trường hợp đa mảng .... ví dụ:

(lưu ý: tôi đã không thấy làm thế nào để có được sự quá tải làm việc với boost::multi_array<T,N>::reference, xin đừng đặt nó vào sử dụng hiệu quả với phiên bản detail:: này;)

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); 
} 
+0

Điều này có thể được giải quyết thanh lịch bằng cách sử dụng boost :: enable_if_c và boost :: traits? –

+0

MA :: tham chiếu ref = m1 [0] dòng chắc chắn không phải là ngắn gọn cú pháp, nhưng nó không nhìn để thêm chi phí đáng kể tại thời gian chạy cho std :: vector trường hợp. Gần đây tôi đã chạy afoul của cùng một vấn đề: http://old.nabble.com/-multiarray--problems-passing-views-by-reference-td27039405.html –

+0

@quant_dev: cũng có vấn đề về lý do tại sao sử dụng 'boost :: multi_array :: tham chiếu' trực tiếp không hoạt động, tôi không có thời gian để điều tra thêm. –

Các vấn đề liên quan