2016-12-16 14 views
10

Hãy xem xét một ví dụ:Tại sao lambda không thể, khi truyền đến con trỏ hàm, được sử dụng trong ngữ cảnh constexpr?

template <void (*Foo)()> 
struct S { 
}; 

int main() { 
    struct A { 
     static void x() { } 
    }; 
    S<&A::x> s; 
} 

mã biên dịch trong kêu vang, gcc cho rằng x không có một mối liên hệ ... Ví dụ khá giống chỉ khi sử dụng biểu thức lambda:

template <void (*Foo)()> 
struct S { 
}; 

int main() { 
    auto lambda = []{}; 
    S<+lambda> s; 
} 

Cả gcc và clang đều đồng ý không biên dịch mã: theo gcc hàm trả về bởi unary + không có liên kết, clang nói ngược lại rằng toán tử cast cho hàm không được khai báo là constexpr. Có bất kỳ lý do nào để không cho phép truyền lambda tới con trỏ hàm được sử dụng trong ngữ cảnh constexpr không?

Tìm dưới đây lỗi được tạo ra bởi trình biên dịch và trình diễn trực tiếp:

gcc:

prog.cc:7:14: error: 'main()::::_FUN' is not a valid template argument for type 'void (*)()' because 'static constexpr void main()::::_FUN()' has no linkage

clang:

prog.cc:7:8: note: non-constexpr function 'operator void (*)()' cannot be used in a constant expression

+2

'lambda' không liên kết vì http://eel.is/c++draft/basic.link#8 và dĩ nhiên toán tử'() không phải là 'constexpr', do đó, đó là vấn đề những gì lỗi được phát ra đầu tiên - Tôi có sai không? – skypjack

+0

@skypjack Đó là cùng một kết luận tôi đã đến, sau một chút tìm kiếm xung quanh (đó là lý do tương tự như tại sao 'A' không có liên kết). Và, ngoài ra, các loại không có liên kết, không thể được sử dụng làm đối số mẫu. –

Trả lời

10

Clang hasn't implemented constexpr lambdas yet.

GCC ở đằng sau theo những cách khác. [temp.arg.nontype]/2 's hạn chế thú vị duy nhất là đối số sẽ là một biểu thức liên tục. Nhưng [expr.const]/(5.2) làm cho nó một, vì vậy đó là hoàn toàn hợp lệ. Có lẽ GCC đã không thực hiện N4198 được nêu ra, mà loại bỏ các yêu cầu liên kết.

Lưu ý rằng cả hai đối số mẫu con trỏ hàm constexpr lambdas và không liên kết đều có tính năng đăng C++ 14.

+0

Vì vậy, mã nên hợp lệ kể từ C++ 14? –

+2

Không, không phải là phần 'constexpr'lambdas của C++ 14, cũng không được kết hợp với N4198. – Columbo

+0

Cảm ơn! Tôi chỉ muốn chắc chắn :) –

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