2017-05-03 18 views
8

Tôi gặp vấn đề tương tự với this một vấn đề.Sự không thống nhất với tình trạng noexcept và quá tải có điều kiện

Tóm lại, tôi có phương thức magic, là noexcept nếu phương pháp khác là noexcept.

Điều kỳ lạ là "phương pháp khác" này có hai lần quá tải và trình biên dịch chọn quá tải giây thứ hai để xác định magicnoexcept -ness.

Tuy nhiên, khi magic được gọi sau này, các quá tải đầu tiên được gọi, nhưng noexcept -ness của magic vẫn giữ nguyên!

Đây là wandbox link

Từ những gì tôi hiểu:

  1. noexcept(magic(dummy2{})) cuộc gọi
  2. noexcept(noexcept(adl_caller(...)) mà rơi trở lại
  3. adl_caller(..., priority_tag<0>) noexcept từ user_method(dummy2) không biết đến bởi trình biên dịch vào thời điểm này.

Đủ công bằng, tuy nhiên, cách user_method(dummy2) được gọi là 3 dòng ở trên? Đây có phải là tiêu chuẩn của tiêu chuẩn không?

Xin lỗi nếu tôi không đủ rõ ràng.

#include <iostream> 

template <unsigned N> struct priority_tag : priority_tag<N - 1> {}; 
template <> struct priority_tag<0> {}; 

template <typename T> 
auto adl_caller(T t, priority_tag<1>) noexcept(noexcept(user_method(t))) 
    -> decltype(user_method(t)) { 
    std::cout << "first adl_caller overload" << std::endl; 
    user_method(t); 
} 

// tricky noexcept ... 
template <typename T> void adl_caller(T, priority_tag<0>) noexcept { 
    std::cout << "second adl_caller overload" << std::endl; 
} 

template <typename T> 
void magic(T t) noexcept(noexcept(adl_caller(t, priority_tag<1>{}))) { 
    adl_caller(t, priority_tag<1>{}); 
} 

struct dummy {}; 
struct dummy2 {}; 

// un-commenting this line makes the above call to cout print '0' 
// void user_method(dummy2); 

void user_method(dummy) 
{ 
    // user_method(dummy2) is declared after this point 
    // this line prints '1', since magic falls back to the second adl_caller overload 
    std::cout << "noexcept?: " << noexcept(magic(dummy2{})) << std::endl; 
    std::cout << "dummy method called" << std::endl; 
    // however, the first adl_caller overload is called here ... 
    magic(dummy2{}); 
} 

void user_method(dummy2) 
{ 
    std::cout << "dummy2 method called" << std::endl; 
} 

int main() 
{ 
    magic(dummy{}); 
} 

Trả lời

6

[temp.point]/8:

Một chuyên môn hoá cho một hàm mẫu [...] có thể có nhiều điểm của sự khởi tạo trong một đơn vị dịch thuật và ngoài các điểm instantiation mô tả ở trên, cho bất kỳ chuyên môn nào như vậy có điểm khởi tạo trong đơn vị dịch , phần cuối của đơn vị dịch cũng được coi là điểm khởi tạo . [...] Nếu có hai điểm khác nhau của việc diễn giải cung cấp cho chuyên môn mẫu ý nghĩa khác nhau theo quy tắc một định nghĩa, chương trình bị lỗi, không cần chẩn đoán .

Hãy so sánh [temp.dep.candidate]:

Đối với một cuộc gọi chức năng nơi postfix thể hiện là một phụ thuộc tên, chức năng ứng cử viên được tìm thấy bằng cách sử dụng quy tắc tra cứu thông thường ([basic.lookup.unqual ], [basic.lookup.argdep]) ngoại trừ:

  • Đối với phần tra cứu bằng tra cứu tên không đủ tiêu chuẩn, chỉ vui khai báo ction từ ngữ cảnh định nghĩa mẫu được tìm thấy.

  • Đối với phần tra cứu bằng cách sử dụng các không gian tên được liên kết ([basic.lookup.argdep]), chỉ có các khai báo hàm được tìm thấy trong ngữ cảnh định nghĩa mẫu hoặc ngữ cảnh instantiation mẫu .

Nếu cuộc gọi sẽ được vô hình thành hoặc sẽ tìm thấy một trận đấu tốt hơn đã tra cứu trong không gian tên có liên quan xem xét tất cả các chức năng tờ khai với mối liên hệ bên ngoài giới thiệu trong những không gian tên trong tất cả các đơn vị dịch thuật, không chỉ xem xét những tuyên bố đó được tìm thấy trong định nghĩa mẫu và bối cảnh tức thì mẫu, sau đó chương trình có hành vi không xác định.

+0

Tôi nghĩ rằng tôi hiểu một số phần của các đoạn văn đó, nhưng chúng hơi quá tối nghĩa với tôi. Tôi chỉ có một TU và không có hàm liên kết bên ngoài trong ví dụ của tôi, đoạn cuối cùng liên quan đến mã tôi đã liên kết như thế nào? Nếu tôi hiểu chính xác, phương pháp 'ma thuật' được liên kết với đoạn đầu tiên, nhưng tôi có một số rắc rối khi nắm được lý do chính xác. Cảm ơn rất nhiều cho các trích đoạn tiêu chuẩn mặc dù – Dante

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