2011-12-29 20 views
12

Có an toàn để giả định rằng hai con trỏ hàm, trỏ đến các trường hợp khác nhau của một hàm templated, sẽ so sánh không bằng nhau? Ngay cả khi các chức năng templated không sử dụng các tham số mẫu (s) ở tất cả và do đó không chính xác điều tương tự trong mọi trường hợp?Con trỏ đến các trường hợp khác nhau của một chức năng templated đảm bảo để so sánh bất bình đẳng?

Ví dụ sau đây hoạt động tốt trên trình biên dịch của tôi, nhưng tôi không chắc chắn nếu nó trên bất kỳ khác:

class TypeChecker 
{ 
public: 
    template< typename T > static void foo(void) 
    {} 
    template< typename T > static void setType(void) 
    { s_fooPtr = &foo<T>; } 
    template< typename T > static bool checkType(void) 
    { return (s_fooPtr == &foo<T>); } 
private: 
    static void (* s_fooPtr)(void); 
}; 

void (* TypeChecker::s_fooPtr)(void) = 0; 

int main(void) 
{ 
    TypeChecker::setType<char>(); 
    TypeChecker::checkType<char>();   // true 
    TypeChecker::checkType< unsigned char >(); // false 
    TypeChecker::checkType< signed char >(); // false 
} 

Trả lời

10

Khi hai con trỏ sẽ so sánh bằng nhau?

Theo 5.10/1:

Các == (bằng) và = (không bằng) các nhà khai thác có cùng hạn chế ngữ nghĩa, chuyển đổi, và các loại quả như quan hệ các toán tử ngoại trừ kết quả ưu tiên thấp hơn và giá trị true-value của chúng. [ Lưu ý: a<b == c<d là đúng bất cứ khi nào a<bc<d có cùng giá trị thật. —end note] Các con trỏ cùng loại (sau khi chuyển đổi con trỏ) có thể là so với bình đẳng. Hai con trỏ cùng loại so sánh bằng và chỉ khi chúng đều là rỗng, cả hai đều trỏ đến cùng một hàm, hoặc đều thể hiện cùng một địa chỉ (3.9.2).

Có phải foo<int>()foo<char>() có cùng chức năng không?

Theo 14,4/1:

Hai mẫu-id tham khảo các lớp học hoặc chức năng tương tự nếu

  • họ template-tên, điều hành chức năng-id, hoặc đen-điều hành -trường tham chiếu cùng một mẫu và
  • mẫu đối số tương ứng của chúng cùng loại
  • hiệu chỉnh của chúng nding phi kiểu mẫu đối số của tích phân hoặc liệt kê loại có giá trị giống nhau và
  • của họ tương ứng phi kiểu mẫu-tham số kiểu con trỏ tham khảo các đối tượng bên ngoài cùng hoặc chức năng hoặc là cả giá trị con trỏ null và
  • đối số mẫu không kiểu tương ứng của chúng của kiểu con trỏ tới thành viên tham chiếu đến cùng một thành phần lớp hoặc là cả giá trị con trỏ thành viên null và
  • các đối số mẫu không kiểu tương ứng của chúng tham chiếu đến cùng một bên ngoài đối tượng hoặc chức năng và
  • mẫu tương ứng của chúng các đối số mẫu tham chiếu đến cùng một mẫu.

Vì vậy, rõ ràng foo<int>()foo<char>() không phải là chức năng tương tự.

Vì vậy, &foo<int>()&foo<char>() không được so sánh bằng nhau, bất kỳ tối ưu hóa nào được thực hiện.


EDIT:

Như đã đề cập bởi @SergeDundich trong các bình luận, 14,4/1 sử dụng if thay if and only if, mang đến cho có gì đảm bảo liệu foo<int>()foo<char>() là những chức năng tương tự hay không. Trong các phần khác của đặc điểm kỹ thuật, if and only if được sử dụng rất nhiều.

Tôi không tìm thấy bất kỳ giải thích nào về điều này trong đặc điểm kỹ thuật. Tuy nhiên, trong các ví dụ, tôi có thể tìm thấy điều này:

template<class T, void(*err_fct)()> class list { /* ... */ }; 
list<int,&error_handler1> x1; 
list<int,&error_handler2> x2; 
list<int,&error_handler2> x3; 
list<char,&error_handler2> x4; 

tuyên bố x2 và x3 là cùng loại. Loại của chúng khác với từ các loại loại x1 và x4.


EDIT2:

if được sử dụng thay vì if and only if như tình trạng này tồn tại: (Ví dụ từ 14.5.7/2)

template<class T> struct Alloc { /* ... */ }; 
template<class T> using Vec = vector<T, Alloc<T>>; 
Vec<int> v; // same as vector<int, Alloc<int>> v; 

Vec<int>vector<int, Alloc<int>> có rất nhiều của sự khác biệt, nhưng vẫn cùng loại.

Tuy nhiên, đối với trường hợp foo<int>()foo<char>(), chữ ký của chúng khác nhau. Các chữ ký khác nhau sẽ hiển thị các hàm khác nhau.

Nhờ @ JohannesSchaub-litb.

+0

Điều gì về "chức năng" trong 3.9.2? Từ ngữ đó bằng cách nào đó hàm ý một hàm là một đối tượng có địa chỉ. – sharptooth

+1

@fefe: "Hai mẫu-id tham chiếu đến cùng một lớp hoặc hàm ** nếu **" Nhưng không "nếu và chỉ khi". Bạn có lưu ý không? IMO Điều đó rất quan trọng. Và IMO kết luận của bạn rằng "' foo () 'và' foo () 'không phải là cùng một chức năng" là sai. Chúng rõ ràng không được yêu cầu bởi tiêu chuẩn để có cùng chức năng nhưng dấu ngoặc kép của bạn không chứng minh rằng chúng được yêu cầu là ** không cùng chức năng **. –

+0

@sharptooth: Trong 3.9.2/2, con trỏ được chia thành 'loại con trỏ đối tượng' và' kiểu con trỏ hàm'. Kiểu con trỏ đối tượng được định nghĩa là "kiểu ** con trỏ thành ** void hoặc ** con trỏ đến ** một kiểu đối tượng được gọi là kiểu con trỏ đối tượng.", Tuy nhiên "Kiểu con trỏ có thể ** chỉ định ** một hàm được gọi là kiểu con trỏ hàm. " Dường như đặc điểm kỹ thuật là tránh việc sử dụng "con trỏ đến" cho con trỏ hàm. Và sau đó, chỉ loại đối tượng con trỏ được gọi là 'đại diện cho một trong hai địa chỉ của một byte trong bộ nhớ (1.7) hoặc một con trỏ null (4.10) .'. – fefe

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