2013-04-13 36 views
21

Tôi đã đọc this và đang cố gắng hiểu những gì N3601 là về. Nó nói thành ngữ này xuất hiện rất nhiều trong một tìm kiếm trên web, nhưng tôi không thể tìm thấy bất cứ điều gì. Các thành phầnMẫu <typename T, T t> thành ngữ là gì?

template<typename T, T t> 

thành ngữ nào, cách giải quyết, cách sử dụng, thông số mẫu ngầm định là gì và đề xuất nhằm khắc phục điều gì?

+2

Bắt đầu bằng mẫu 'template void foo (T t);'. Đặt tham số đó thành giá trị biên dịch: 'template void bar();' (tôi nghĩ bạn có nghĩa là thay vì 'class'). Bây giờ nghĩ về cách bạn có thể gọi 'foo (5);' cho T là 'int', nhưng để làm điều đó với' bar', bạn cần 'bar ();'. Điều đó có đi đúng hướng không? – chris

+0

Tôi đã có nghĩa là T t, không phải lớp T. Cố định điều đó. –

+0

@chris Tôi biết bạn đang đi đâu. thanh cần phải chung chung trên bất kỳ loại nào chúng tôi cung cấp, nhưng cũng lấy giá trị của cùng một loại như một tham số mẫu khác. Chúng ta cần xác định cả kiểu và giá trị của nó để suy luận rằng 5 là một int. Đề xuất cho thấy việc sử dụng điều này trong thư viện phản ánh, nhưng tôi chưa bao giờ thấy nó cho đến ngày hôm nay. Làm thế nào khác có thể được sử dụng? –

Trả lời

15

Sự cố đang được giải quyết là loại trừ các loại từ thông số không phải mẫu.

Given:

template<typename T> void foo(T); 
template<typename T, T> void bar(); 

người ta có thể suy ra T cho foo (ví dụ, foo(10) sẽ dẫn đến T được suy luận là int), nhưng nó không thể suy ra T cho bar (bar<10>() sẽ đơn giản là không biên dịch, bạn phải viết nó là bar<int,10>()).

N3601 đề xuất sửa chữa điều này bằng cách giới thiệu cú pháp:

template<using typename T, T> void bar(); 

mà sẽ cho phép bar<10>() để biên dịch và gây ra các loại T được suy luận.

5

Việc giới thiệu giấy là sai lầm: thành ngữ thực sự là

template <typename T, T t> 

Nó biểu thị một mẫu mà phụ thuộc vào một loại T và một giá trị t của loại đó. Ký hiệu hơi nặng vì trong hầu hết các trường hợp, kiểu có thể được suy ra từ chính giá trị đó.

Ví dụ:

// the current definition notation 
template <typename T, T t> void f() { t.f(); }; 

//// the proposed definition notation 
//// the parameter t depends on an implicit typename parameter T 
// template <using typename T, T t> void f() { t.f(); }; 

struct foo { 
    void f(){ 
     // some computation 
    } 
}; 

foo bar; 

int main(){ 
    // the current instantiation notation 
    f<foo,bar>(); 
    //// the proposed instantiation notation 
    //// we know that bar is of type foo, so we don't need to specify it 
    // f<bar>(); 
} 

Đề xuất giới thiệu một chút "đường cú pháp" để làm cho ký hiệu dễ viết hơn. Ngoài ra, ví dụ ở trên là tầm thường trong mô tả của nó (và có thể sai, vì thông số mẫu cần phải là constexpr), nhưng bài báo mô tả một số tình huống mà ký pháp hiện tại có thể trở nên khá lông, giảm khả năng đọc và dễ dàng tổng thể lập trình.

+0

và giá trị 't' của loại đó phải là một hằng số không thể tách rời, hoặc một con trỏ bởi vì không có gì khác được cho phép trong các đối số mẫu. –

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