2012-12-05 33 views
7

Trong trường hợp lỗi thay thế liên quan đến bí danh mẫu (ví dụ: bí danh mẫu trên tên tệp thành viên bị thiếu, như trong đoạn mã bên dưới), có nên kích hoạt lỗi không?bí danh mẫu và sfinae

Clang và gcc dường như không đồng ý về vấn đề này:

// some types 
struct bar { }; 

struct foo { 
    typedef void member_type; 
}; 


// template alias 
template<class T> 
using member = typename T::member_type; 


template<class T> 
void baz(...) { } 

// only works for gcc, clang fails with: no type named 'member_type' 
// in 'bar' 
template<class T> 
void baz(member<T>*) { } 


int main(int, char**) { 

    baz<bar>(0);   // picks first 
    baz<foo>(0);   // picks second 

    return 0; 
} 

Vì vậy, câu hỏi là: ai là đúng, và tại sao?

Cảm ơn :-)

+0

'clang -v' nói gì? Clang 3.3 trunk biên dịch mã chỉ tốt. – Xeo

+0

Debian clang phiên bản 3.1-8 tại đây, có vẻ như tôi chỉ cần đợi. Cảm ơn phản hồi của bạn ! – max

+0

Bạn có thể loại bỏ bí danh mẫu, chỉ để đơn giản hóa mọi thứ một chút – David

Trả lời

4

Theo tiêu chuẩn, nó rõ ràng là GCC đó là chính xác, bởi vì mẫu bí danh ngay lập tức phải được thay thế và sau đó bình thường/thường SFINAE được áp dụng cho typename T::member_type sau khi T được biết đến.

Nhưng hiện tại có sự cố về vấn đề này, hãy xem http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1554.

Theo kết quả cuộc họp, có vẻ như hành vi kêu vang là: Thay thế T sẽ được thực hiện trong bối cảnh mẫu bí danh (mặc dù tại thời điểm thay thế trong typename T::member_type, không có tham chiếu đến bí danh mẫu nữa - nó sẽ vẫn cần phải được tham chiếu như nguồn của nơi mà kiểu mẫu tham số bắt nguồn từ, nếu đây là cách nó được triển khai thực hiện).


này tương tự như một tình huống mà các mẫu được vứt bỏ đúng thời hạn xác định có thể ảnh hưởng ngữ nghĩa instantiation

template<int I> 
void f(int x[I]); 

int main() { 
    f<0>(nullptr); 
} 

Trong trường hợp này cũng vậy, theo ý kiến ​​của tôi tiêu chuẩn chuẩn mực rõ ràng là tham số là ngay lập tức được thay thế bằng int* và do đó việc khởi tạo hoạt động. Xem http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1322.

+5

"Theo kết quả cuộc họp, nó xuất hiện rằng hành vi kêu vang là mong muốn" - sẽ không hoàn toàn giết bất kỳ bí danh 'EnableIf' ra khỏi đó? Nó * có vẻ * rất không mong muốn để có các mẫu bí danh không tạo ra các lỗi mềm SFINAE. – Xeo

+0

@Xeo có điều đó sẽ rất tệ. Và trên thực tế, clang trunk chấp nhận bí danh 'EnableIf', vì vậy nó xuất hiện với tôi hành vi mà người hỏi đã quan sát chỉ là một lỗi clang, và tóm tắt của vấn đề trên trang wg21 chỉ gây nhầm lẫn (IMHO). –

+0

Vâng, tôi đã nhầm lẫn vì tôi đã nhận xét rằng thân cây biên dịch mã tốt. – Xeo