2011-02-24 34 views
6

Nếu tôi muốn sử dụng một thành viên của một lớp mẫu cơ sở từ một mẫu có nguồn gốc lớp, tôi phải đưa nó vào phạm vi như vậy:C++ sử dụng tuyên bố trong hàm thành viên phạm vi

template <typename T> 
struct base 
{ 
    void foo(); 
}; 

template <typename T> 
struct derived : base<T> 
{ 
    using base<T>::foo; 
}; 

Tại sao không tôi có thể đặt câu lệnh này sử dụng vào một phạm vi cục bộ, giống như các câu lệnh khác?

template <typename T> 
struct base 
{ 
    void foo(); 
}; 

template <typename T> 
struct derived : base<T> 
{ 
    void f() 
    { 
     using base<T>::foo; // ERROR: base<T> is not a namespace 
    } 
}; 
+1

Bạn đang cố gắng giải quyết vấn đề gì bằng cách thực hiện việc này? Bạn đang cố gắng tránh tiền tố tên 'foo' với' this-> '? –

+2

Bằng cách sử dụng khai báo sử dụng, tôi tránh đặt trước tên 'foo' bằng' this-> ', yes. Bằng cách đặt nó trong một phạm vi địa phương, tôi đang cố gắng gây ô nhiễm phạm vi dẫn xuất chỉ khi cần thiết. – HighCommander4

Trả lời

1

Tiêu chuẩn (dự thảo 3225) nói trong [namespace.udecl]:

Một sử dụng-khai cho thành viên lớp sẽ là member- khai báo. [Ví dụ:

struct X { 
    int i; 
    static int s; 
}; 
void f() { 
    using X::i; // error: X::i is a class member 
       // and this is not a member declaration. 
    using X::s; // error: X::s is a class member 
       // and this is not a member declaration. 
} 

- end dụ]

Một sử dụng-chỉ không có hạn chế như vậy, tuy nhiên ([namespace.udir]):

khi nhìn lên một không gian tên-name trong một sử dụng-d irective, chỉ các tên không gian tên được xem là

+0

Tôi hiểu. Bất kỳ ý tưởng về lý do đằng sau điều này? – HighCommander4

+0

Tôi chỉ có thể nghĩ một thứ - điều đó sẽ cho phép bạn có các hàm thành viên và không phải thành viên trong cùng một không gian tìm kiếm tên, có thể không xảy ra theo các quy tắc hiện tại (không có hàm thành viên theo tên riêng biệt ẩn vùng tên chức năng -scoped cùng tên?). Nhưng tôi đoán ADL đã làm điều đó, nên tôi thực sự không biết tại sao. –

2

Mục đích của using base<T>::foo trong phạm vi chức năng là bạn muốn gọi foo trong hàm, và vì nó mang lại cho lỗi, bạn không thể làm điều đó.

Nếu bạn muốn gọi functon (nếu không tại sao bạn làm điều đó), sau đó bạn có thể làm những được phép:

this->template base<T>::foo(); //syntax 1 
this->base<T>::foo();   //syntax 2 - simple 
this->foo();     //syntax 3 - simpler 

Tuy nhiên, bạn không thể viết này:

foo() ; //error - since foo is in base class template! 
//if you write `using base<T>::foo` at class scope, it will work! 

Bản trình diễn tại ideone: http://www.ideone.com/vfDNs

Đọc thông tin này khi bạn phải sử dụng template từ khóa trong một cuộc gọi chức năng:

Ugly compiler errors with template

+1

I * can * gọi 'foo()' mà không có bất kỳ trình độ nào nếu tôi đặt 'using base :: foo' vào phạm vi lớp trong lớp dẫn xuất. – HighCommander4

+0

@ HighCommander4: 'sử dụng base :: foo' không cần thiết ngay cả ở phạm vi lớp nếu bạn muốn gọi' foo' từ 'f()'. – Nawaz

+0

Cho dù sử dụng 'this->' này đơn giản hơn việc sử dụng 'sử dụng base :: foo' là một vấn đề ưu tiên. Tôi chỉ cần viết 'bằng cách sử dụng cơ sở :: foo' một lần, trong khi tôi sẽ cần phải viết' this-> 'ở phía trước của mọi cuộc gọi đến' foo() '. – HighCommander4

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