2016-03-08 22 views
7

Hãy xem xét các đoạn mã sau:Chúng tôi có thể tham khảo các biến thành viên trong một đặc tả không được chấp nhận không?

template<class Tuple> 
class vector 
{ 
public: 
    typename Tuple::size_type size() const noexcept(noexcept(m_elements.size())) { 
     return m_elements.size(); 
    } 

private: 
    Tuple m_elements; 
}; 

class tuple 
{ 
public: 
    using size_type = std::size_t; 

    size_type size() const { return 0; } 
    size_type size() noexcept { return 0; } 
};  

int main() 
{ 
    vector<tuple> x; 
    static_assert(noexcept(x.size()), "x.size() might throw"); 

    return 0; 
} 

là việc sử dụng các biến thành viên m_elements bên trong noexcept specifier quy phạm pháp luật? GCC 5.2 (C++17) yields the compiler errorm_elements không được khai báo trong phạm vi này. trong khi clang 3.6 (C++17) compiles without any error.

Cả hai trình biên dịch đều không có lỗi nếu tôi sử dụng noexcept(std::declval<Tuple const&>().size()) để thay thế. Tuy nhiên, như bạn có thể thấy, tôi đã tạo một lớp ví dụ đơn giản tuple nơi điều quan trọng là có hay không Tuple có quá tải đủ điều kiện là size.

Từ quan điểm của tôi, đó là trực quan hơn để viết noexcept(m_elements.size()) nguyên nhân đó là chính xác những cú điện thoại lúc cơ quan chức năng và nó sẽ đưa vào tài khoản đó phương pháp size của vectorconst đủ tiêu chuẩn (mà làm m_elements một đối tượng const trong phạm vi chức năng).

Vì vậy, việc sử dụng hợp pháp là gì? Nếu cả hai đều tương đương, tôi nên sử dụng cái nào? Tôi có nên sử dụng noexcept vòng loại nào cả trong trường hợp này không? Vấn đề là có hay không các chức năng vector sẽ ném tùy thuộc vào hầu hết mọi trường hợp trên Tuple.

+0

Tôi muốn lưu ý rằng có [đã có một câu hỏi liên quan đến việc sử dụng các biến thành viên bên trong một đặc tả 'noexcept'] (http://stackoverflow.com/questions/27241938/noexcept-depending-on-method-of -member) ở đây trên diễn đàn, nhưng xin lưu ý rằng câu hỏi này liên quan đến C++ 11 và lỗi trình biên dịch được tạo bởi (một số phiên bản không rõ) của clang. – 0xbadf00d

Trả lời

5

Clang đúng ở đây, đây là lỗi gcc. Theo [basic.scope.class], tôi nhấn mạnh:

Phạm vi tiềm năng của một tên tuyên bố trong một lớp học bao gồm không chỉ của khu vực tường thuật sau đây quan điểm tên của tờ khai, mà còn của tất cả các cơ quan chức năng, đối số mặc định, ngoại lệ -specificationsdấu ngoặc đơn hoặc số lần khởi tạo bằng nhau của các thành viên dữ liệu không tĩnh trong lớp đó (bao gồm những thứ như vậy trong lồng nhau lớp).

Phạm vi m_elements bao gồm các noexcept-đặc điểm kỹ thuật cho size().

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