2015-06-28 26 views
5

Tôi nhận được kết quả khác nhau bằng tự động và sử dụng Vector khi tổng hợp hai vectơ.Kết quả sai khi sử dụng tự động với Eigen

Mã của tôi:

#include "stdafx.h" 
#include <iostream> 
#include "D:\externals\eigen_3_1_2\include\Eigen\Geometry" 

typedef Eigen::Matrix<double, 3, 1>  Vector3; 

void foo(const Vector3& Ha, volatile int j) 
{ 
    const auto resAuto = Ha + Vector3(0.,0.,j * 2.567); 
    const Vector3 resVector3 = Ha + Vector3(0.,0.,j * 2.567); 

    std::cout << "resAuto = " << resAuto <<std::endl; 
    std::cout << "resVector3 = " << resVector3 <<std::endl; 
} 

int main(int argc, _TCHAR* argv[]) 
{ 
    Vector3 Ha(-24.9536,-29.3876,65.801); 
    Vector3 z(0.,0.,2.567); 

    int j = 7; 

    foo(Ha,j); 
    return 0; 
} 

Kết quả:

resAuto = -24,9536, -29.3876,65.801

resVector3 = -24,9536, -29.3876,83.77

Press bất kỳ chìa khóa nào để tiếp tục. . .

Tôi hiểu rằng Eigen tối ưu hóa nội bộ tạo ra các kết quả khác nhau. Nhưng nó trông giống như một lỗi trong Eigen và C++ 11.

+1

Nếu có vẻ như "lỗi trong Eigen và C++ 11", có thể không phải như vậy. Đọc kỹ tài liệu một lần nữa, chú ý cẩn thận đến các mẫu biểu hiện. –

+0

Nó hoạt động thành công cho tôi với eigen 3.2.2. – user2658323

+0

Mẫu biểu thức và các lớp khác trả về loại proxy (vector :: toán tử [] (size_t)) có thể gây ngạc nhiên khi được sử dụng với tự động. Thay vì nhận được tổng của vectơ của bạn, bạn đang nhận được một loại lưu trữ các biểu hiện của tổng của hai vectơ của bạn. Đây là một tối ưu hóa mẫu thường được sử dụng cho các đối tượng trực tiếp lớn. Trong một tin tức khác, đã có một đề xuất cho 'nhà điều hành tự động' mà có thể cho phép tác giả lớp Eigen trả lại một Vector3 thực tế trong trường hợp của bạn. Tôi biết gcc và tôi nghĩ rằng clang đã snuck nó in Có thể hack 'điều hành tự động của riêng bạn' và xem. – emsr

Trả lời

2

Từ khóa auto yêu cầu trình biên dịch "đoán" đối tượng tốt nhất dựa trên bên phải của =. Bạn có thể kiểm tra kết quả bằng cách thêm

std::cout << typeid(resAuto).name() <<std::endl; 
std::cout << typeid(resVector3).name() <<std::endl; 

để foo (đừng quên để bao gồm <typeinfo>).

Trong trường hợp này, sau khi xây dựng tạm thời Vector3, phương thức operator+ được gọi, tạo đối tượng CwiseBinaryOp. Đối tượng này là một phần của Eigens lazy evaluation (có thể tăng hiệu suất). Nếu bạn muốn buộc đánh giá háo hức (và do đó hãy xác định loại), bạn có thể sử dụng

const auto resAuto = (Ha + Vector3(0.,0.,j * 2.567)).eval(); 

thay vì dòng của bạn trong foo.

Một vài lưu ý phụ:

  • Vector3 là giống hệt với lớp Vector3d quy định tại Eigen
  • Bạn có thể sử dụng #include <Eigen/Core> thay vì #include <Eigen/Geometry> để bao gồm hầu hết các tiêu đề Eigen, cộng với những điều nào đó được định nghĩa đó mà nên là.
Các vấn đề liên quan