2010-09-14 32 views
5

Tôi đã tìm thấy trường hợp kỳ lạ này của một số mã (bên dưới) không biên dịch theo Visual Studio 2008 và tạo ra "lỗi C2872: 'Sự mơ hồ': biểu tượng mơ hồ "trên dòng 12.Lỗi biên dịch VS2008 (+?) Với chức năng templated và 'sử dụng không gian tên'

Xóa việc sử dụng namespace RequiredNamespace trên dòng cuối cùng khắc phục lỗi, nhưng tôi hy vọng rằng việc đặt using namespace ở cuối tệp sẽ không có hiệu lực. Nó cũng dựa trên AnotherFunction là một hàm mẫu, vì vậy tôi hy vọng trình biên dịch sẽ tạo ra các chức năng templated trong phạm vi sai, hoặc không đặt lại danh sách các không gian tên được sử dụng trước khi làm như vậy.

Cùng mã biên dịch theo GCC.

Cả hai trình biên dịch dường như tạo mã cho TemplatedFunction sau định nghĩa using namespace Namespace, ít nhất là tôi có thể biết bằng cách giới thiệu lỗi và xem thứ tự chúng xuất.

namespace Ambiguity 
{ 
    class cSomeClass 
    { 
    }; 

    template<class T> 
    void TemplatedFunction(T a) 
    { 
     // this is where the error occurs, the compiler thinks Ambiguity 
     // might refer to the class in RequiredNamespace below 
     Ambiguity::cSomeClass(); 
    } 
} 

namespace RequiredNamespace 
{ 
    // without a namespace around this class, the Ambiguity class 
    // and namespace collide 
    class Ambiguity 
    { 
    }; 
} 

int main() 
{ 
    // to force the templated function to be generated 
    Ambiguity::TemplatedFunction(4); 
} 

// removing this removes the error, but it shouldn't really do anything 
using namespace RequiredNamespace; 

Rõ ràng đây là một ví dụ chế tạo, nhưng bản gốc được chiết xuất từ ​​một trường hợp thực tế nơi using namespace là trong một file tự động tạo ra bởi mã bên thứ 3.

Đây có phải là lỗi trong trình biên dịch không?

+1

là tôi hay đây thực sự là một ví dụ khó đọc, với những số nhận dạng cụ thể này? –

+0

Đặt trước - không chỉ riêng bạn. –

+0

Tôi làm cách nào để đơn giản hơn?Tôi đoán một phần của vấn đề là nếu quy ước đặt tên được theo sau, vấn đề sẽ không xảy ra - nếu bạn đặt trước các lớp của bạn với c ví dụ, bạn sẽ không có một lớp gọi là mơ hồ. Tôi đã tinh chỉnh nó một chút. – eAi

Trả lời

2

Tôi tin rằng đó là một lỗi, mỗi 7.3.4 para 1 của tiêu chuẩn C++ 03:

Một sử dụng-chỉ thị xác định rằng tên trong không gian tên được đề cử có thể được sử dụng trong phạm vi trong đó chỉ thị sử dụng xuất hiện sau chỉ thị sử dụng.

Vì vậy, tệp cuối cùng của bạn bằng cách sử dụng khai báo sẽ không có hiệu lực.

5

Tôi đồng ý rằng đó là lỗi, nhưng một số thông tin chi tiết về những gì đang diễn ra có thể bị ngăn cản bằng cách tạo danh sách lắp ráp tương ứng với tệp của bạn (sử dụng tùy chọn/Fa của cl.exe).

Vì vậy, hãy nhận xét khai báo sử dụng, tạo tệp .asm và mở tệp đó trong trình chỉnh sửa văn bản. Quét tệp và bạn có thể thấy rằng bản mẫu của bản mẫu ở cuối tệp (nó bắt đầu bằng [email protected]@[email protected]@[email protected] PROC) và nó nằm trong bản được tạo cho hàm chính (bắt đầu bằng _main PROC). Thông báo lỗi cho biết "xem tham chiếu đến instantiation mẫu chức năng", do đó, nó đề cập đến instantiation của các chức năng mẫu, và danh sách lắp ráp làm rõ rõ ràng này instantiation là ở dưới cùng của tập tin.

Bây giờ, hãy chỉnh sửa mã để thay thế hàm mẫu bằng NonTemplatedFunction(int a) và biên dịch, tạo danh sách lắp ráp. Xem danh sách lắp ráp và bạn sẽ thấy mã lắp ráp được tạo cho NonTemplatedFunction(int a) xuất hiện phía trên _main PROC.

Tất cả điều này có nghĩa là gì? Khi trình biên dịch Visual Studio 2008 biến mẫu của bạn thành mã thực tế, nó có hiệu quả gắn thêm một số mã vào cuối tệp của bạn sau khi khai báo sử dụng của bạn. Tuyên bố sử dụng của bạn có nghĩa là tên trong mã được tạo tự động là "mơ hồ". Quá trình gcc sử dụng để khởi tạo các mẫu rõ ràng tránh được vấn đề này.

+0

+1: Nếu bạn thay đổi nó thành một chức năng không có khuôn mẫu, Intellisense sẽ khiếu nại nhưng tệp sẽ biên dịch. – Puppy

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