2013-03-13 30 views
6

Tôi đã viết một số mã C++ để làm toán học vector. Đó là điều cần thiết chỉ là một wrapper mỏng xung quanh một ví dụ std::array. Tôi muốn quá tải hàm không phải là thành viên begin() để trả về một trình lặp vào đầu mảng sao lưu. Để làm điều này, tôi đã viết một hàm người bạn đơn giản với loại trả về auto và loại trả về theo sau sử dụng decltype mà chỉ chuyển tiếp cuộc gọi đến biến thành viên.Decltype và chức năng của bạn bè trong Visual Studio vs G ++

Nó sẽ không biên dịch, và tôi không thể hiểu tại sao. Tôi bắt đầu nghịch ngợm xung quanh với một ví dụ nhỏ hơn và phát hiện mã sau đây biên dịch theo G ++ 4.7, nhưng không phải dưới Visual Studio 2012 Professional mới nhất.

#include <iostream> 
#include <array> 

template <typename T, size_t size> 
class MyClass { 

private: 
    std::array<T, size> elts; 

public: 
    friend auto begin(MyClass &a) -> decltype (std::begin(a.elts)) { 
     return std::begin(a.elts); 
    } 

}; 

int main(void) { 
    MyClass<int, 8> instance; 
    auto it = begin(instance); 
    std::cout << *it << std::endl; 
    return 0; 
} 

Điều kỳ lạ là mã này chỉ được biên soạn trong G ++ nếu việc kê khai riêng của elts đến trước khi khai báo của begin() chức năng.

Trong mọi trường hợp, trình biên dịch nào ở ngay đây? Visual Studio hoặc G ++?

Sửa: Các lỗi biên dịch rằng VS2012 đã là error C2228: left of '.elts' must have class/struct/union

Trả lời

7

Định nghĩa của lớp mẫu MyClass là không hoàn thành do thời gian bạn sử dụng biểu thức std::begin(a.elts), vì vậy tôi đoán VC có một lý do để phàn nàn. Bạn không thể sử dụng operator . trên loại không đầy đủ.

Trong mọi trường hợp, bạn có thể làm việc xung quanh đó bằng cách sử dụng như sau:

#include <iostream> 
#include <array> 

template <typename T, size_t size> 
class MyClass 
{ 
    // ... 

    friend typename std::array<T, size>::iterator begin(MyClass &a) 
    //  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
    { 
     return std::begin(a.elts); 
    } 
}; 
+0

Tại sao là 'typename' cần thiết ở đây? –

+2

@duiu: Vì 'std :: array ' là một kiểu phụ thuộc. – ildjarn

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