8

Tôi chỉ nhận ra rằng cố gắng để có được kiểu trả về của một hàm thông qua decltype không liên quan đến ADL (đối số phụ thuộc-tra cứu) trên VS2012 (thử nghiệm bằng cách sử dụng cl.exe V17.00.60610.1).Không có ADL bên trong decltype trên VS2012

sau Ví dụ

#include <stdio.h> 
#include <typeinfo> 

namespace A { 
    int Func(void const *) { 
    printf("A::Func(void const *)\n"); 
    return 0; 
    } 

    template <typename T> void Do(T const &t) { 
    Func(&t); 
    } 
    template <typename T> void PrintType(T const &t) { 
    printf("Type: %s\n", typeid(decltype(Func(&t))).name()); 
    } 
} 

namespace B { 
    struct XX { }; 
    float Func(XX const *) { 
    printf("B::Func(XX const *)\n"); 
    return 0.0f; 
    } 
} 


int main(int argc, char **argv) { 
    B::XX xx; 
    A::Do(xx); 
    A::PrintType(xx); 
    return 0; 
} 

Cho

B::Func(XX const *) 
Type: int 

trên VS2012

nhưng (những gì được dự kiến):

B::Func(XX const *) 
Type: f 

trên gcc 4.7.3.

Vì vậy, ADL hoạt động khi gọi hàm (dòng 1 ở đầu ra) nhưng không khi được sử dụng bên trong decltype trên VS2012.

Hoặc tôi có thiếu một số điểm khác nhau không?

+2

Hỗ trợ 'decltype' của VS2012 khá kém (tìm kiếm" biểu hiện SFINAE "và khóc), vì vậy tôi không ngạc nhiên. – Yakk

+0

nhiều tính năng C++ 11 có rất nhiều chất lượng alpha trong VS2012 và CTP tháng 11 tiếp theo. Giả sử có một danh sách dài các lỗi cố định trong bản xem trước VS2013 (Express hiện có sẵn để tải xuống). Bạn có thể thử vận ​​may của bạn ở đó. – TemplateRex

+0

Vì vậy, những gì về cách cập nhật mới thường xuyên để giải quyết lỗi và thêm các tính năng mới mà MS muốn làm theo kể từ VS2012 ... Vì vậy, những gì ... may mắn thay tôi không bị giới hạn trong lựa chọn trình biên dịch của tôi trong dự án cụ thể này và những giấc mơ được gắn vào VS2013 :-) – mmmmmmmm

Trả lời

2

Một trường hợp thử nghiệm tối thiểu là:

namespace N 
{ 
    struct C {}; 

    C f(C) {}; 
} 

N::C c1; 

decltype(f(c1)) c2; 

Nếu trình biên dịch không hỗ trợ ADL bên decltype, sau đó ở trên sẽ không biên dịch.

Tôi đã nói nó biên dịch, vì vậy có lẽ đó là sự tương tác giữa ADL và mẫu instantiation đó là vấn đề.

+0

Nếu 'c1' được khai báo với không gian tên' N :: C c1; và 'c2' như một hàm (vì MSVS sẽ không chấp nhận một biến kiểu' void'), nó biên dịch. – Pixelchemist

+0

@Pixelchemist: Đã sửa lỗi. Nếu MSVS biên dịch nó, sau đó msvs không có một vấn đề với ADL bên trong decltype trong ít nhất một số trường hợp. –

2

Nếu tìm thấy nó thú vị rằng IDE/Intellisense nào dường như làm tra cứu chính xác nhưng trình biên dịch thì không.

Ví dụ này không hiển thị lỗi intellisense và a được hiển thị là loại size_t khi di chuột lên.

#include <iostream> 
namespace A 
{ 
    struct C {}; 
    size_t f(C*) { return 5U; }; 
} 
namespace B 
{ 
    void f(void *) { }; 
    void f2 (A::C x) 
    { decltype(f(&x)) a; std::cout << typeid(a).name() << std::endl; } 
} 

int main (void) 
{ 
    A::C c; 
    B::f2(c); 
} 

Trình biên dịch dừng bằng Error C2182 và khiếu nại về một loại khoảng trống loại. Có vẻ như đó là vấn đề độc lập của mẫu.

+0

Visual C++ sử dụng giao diện C++ khác nhau cho các tính năng IntelliSense và IDE, do đó, có nhiều khác biệt tinh tế giữa những gì IntelliSense chấp nhận và trình biên dịch chấp nhận. –

+0

Cảm ơn thông tin. Tôi không hoàn toàn ngạc nhiên nhưng thích thú. Tôi chỉ muốn đưa ra gợi ý rằng các mẫu không phải là vấn đề ở đây. – Pixelchemist

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