2016-10-07 20 views
8

P0091R3 ("Template argument deduction for class templates") gần đây đã được thêm vào gcc trunk và có thể được kiểm tra trên wandbox."Khấu trừ đối số mẫu" của C++ 17 cho các mẫu lớp có thể suy ra các kiểu cục bộ không?

Cái gì tôi đã có trong tâm trí là khả năng sử dụng nó để thực hiện một "bảo vệ phạm vi" trong rất ít dòng mã:

scope_guard _([]{ cout << "hi!\n" }); 

tôi đã cố gắng implementing it on wandbox ...

template <typename TF> 
struct scope_guard : TF 
{ 
    scope_guard(TF f) : TF{f} { } 
    ~scope_guard() { (*this)(); } 
}; 

int main() 
{ 
    scope_guard _{[]{}}; 
} 

... nhưng việc biên soạn không thành công với lỗi sau:

prog.cc:6:5: error: 'scope_guard(TF)-> scope_guard<TF> [with TF = main()::<lambda()>]', declared using local type 'main()::<lambda()>', is used but never defined [-fpermissive] 
    scope_guard(TF f) : TF{std::move(f)} { } 
    ^~~~~~~~~~~ 

Sau đó, tôi đã thử using a non-lambda local type và gặp lỗi tương tự.

int main() 
{ 
    struct K { void operator()() {} }; 
    scope_guard _{K{}}; 
} 

Sau đó, I tried a non-local type, và nó làm việc như mong đợi.

struct K { void operator()() {} }; 

int main() 
{ 
    scope_guard _{K{}}; 
} 

Đây có phải là đặc trưng được thiết kế theo cách như vậy có thể ngăn chặn các loại địa phương khỏi bị suy luận?

Hoặc đây có phải là lỗi trong việc triển khai tính năng hiện tại của gcc không?

+1

Có vẻ như bạn đã tìm thấy và nhận xét về báo cáo lỗi. – Barry

Trả lời

7

Đây là lỗi trong quá trình triển khai hiện tại: 77890 ( MỚI ngụ ý hiệu lực, trái ngược với UNCONFIRMED được khắc phục trong 7.0). Có thể suy ra một lambda là một trong những ví dụ động cơ thúc đẩy của giấy ban đầu, vì vậy sẽ là khá vụng về nếu nó không làm việc:

// Virtually impossible to pass a lambda to a template class' constructor without declaring the lambda 
for_each(vi2.begin(), vi2.end(), Foo<???>([&](int i) { ...})); 
for_each(vi.begin(), vi.end(), Foo([&](int i) { ...})); // Now easy instead of virtually impossible 

Chúng ta có thể tạo ra một ví dụ thực sự cơ bản:

template <typename TF> 
struct scope_guard 
{ 
    scope_guard(TF) { } 
}; 

int main() 
{ 
    scope_guard _([]{}); 
} 

này nên thực hiện nghị quyết tình trạng quá tải trên các thiết lập chức năng tổng hợp bao gồm các chức năng:

template <class TF> scope_guard<TF> synthesized(TF); 
template <class TF> scope_guard<TF> synthesized(scope_guard<TF> const&); 
template <class TF> scope_guard<TF> synthesized(scope_guard<TF>&&); 

nên chọn quá tải đầu tiên và sử dụng loại trả về đó là loại _, với TF là loại lambda. Điều này tất cả nên làm việc.

+0

[Đoạn mã gốc bây giờ biên dịch trên ** wandbox **] (http://melpon.org/wandbox/permlink/DOEBWFOU6YyKLPYe). –

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