Tôi có một vấn đề với "nếu constexpr" trong một lambda templated. Vì lợi ích của các đối số chúng ta hãy bỏ qua cách tôi đến đó, nhưng tôi có một foo struct được định nghĩa một cách nào đó để dẫn đến một cái gì đó như sau:False-chi nhánh của nếu constexpr không bị loại bỏ trong templated lambda
template<bool condition>
struct foo {
int a;
// Only contains b if condition is true
int b;
}
Bây giờ tôi có thể định nghĩa một hàm thtemplate templated
template<bool condition>
void print_fun(foo & obj) {
/* Do something with obj.a */
if constexpr(condition)
/* Do something with obj.b */
};
Instantiating chức năng này và sử dụng nó sẽ biên dịch, nếu tham số constexpr để foo
là giống như một đến print_fun
, tức là
constexpr bool no = false;
foo<no> obj = {};
print_fun<no>(obj);
Điều này biên dịch vì nhánh giả bị loại bỏ bên trong một thực thể mẫu, và do đó không có vấn đề gì với việc sử dụng obj.b bên trong print_fun.
Tuy nhiên, nếu tôi xác định một biểu thức lambda tương tự như sau:
template<bool condition>
auto print_lambda = [](foo & obj) {
/* Do something with obj.a */
if constexpr(condition)
/* Do something with obj.b */
};
và nhanh chóng nó:
constexpr bool no = false;
foo<no> obj = {};
print_lambda<no>(obj);
sau đó chi nhánh sai không bỏ đi và trình biên dịch mang lại cho tôi
'b': không phải là thành viên của 'foo'
Hành vi này có dự định không, nó có xảy ra trên các trình biên dịch khác không? Tôi có làm gì sai không? Hoặc là một lỗi trong trình biên dịch? (Microsoft Visual Studio Phiên bản 15.4.1, gcc 7.2)
Kiểm tra thử nghiệm của tôi here với gcc, nơi nó không biên dịch cho hàm hoặc hàm hoặc.
Chỉnh sửa: Đây là mã của một ví dụ tối thiểu của tôi, tôi không biết rằng liên kết bên ngoài sẽ không đủ. Điều này biên dịch trên Visual Studio 15.4.1, ngoại trừ dòng ghi chú. foo_bar
thay thế cho số foo
trong mô tả của tôi.
#include <iostream>
constexpr bool no = false;
struct foo {
int x;
};
struct bar {
int y;
};
template <bool, typename AlwaysTy, typename ConditionalTy>
struct Combined : AlwaysTy {};
template <typename AlwaysTy, typename ConditionalTy>
struct Combined<true, AlwaysTy, ConditionalTy> : AlwaysTy, ConditionalTy {};
using foo_bar = Combined<no, foo, bar>;
template<bool condition>
void print_fun(foo_bar & obj) {
std::cout << obj.x << std::endl;
if constexpr(condition)
std::cout << obj.y << std::endl;
};
template<bool condition>
auto print_lambda = [](foo_bar & obj) {
std::cout << obj.x << std::endl;
if constexpr(condition)
std::cout << obj.y << std::endl;
};
int main(int argc, char ** argv) {
foo_bar obj = {};
print_lambda<no>(obj); // Does not compile
print_fun<no>(obj);
}
"constexpr dùng để tạo foo". constexprs không tạo ra bất cứ điều gì. Nhiều phần câu hỏi của bạn khó hiểu và không thể được phân tích cú pháp. Bạn cần phải bao gồm một [mcve] cụ thể thể hiện lỗi biên dịch mà bạn đang yêu cầu, để mọi người có thể tự xem nó, thay vì phải đoán nó là gì. Và bạn phải bao gồm nó *** trong câu hỏi chính nó ***, thay vì một liên kết đến một số trang web bên ngoài có thể ngừng làm việc bất cứ lúc nào, làm cho câu hỏi vô nghĩa. Hầu hết mọi người trên stackoverflow.com bỏ qua các liên kết bên ngoài trong câu hỏi, vì lý do đó. –
Tôi đã chỉnh sửa câu hỏi của mình để bao gồm ví dụ. Xin lỗi vì sự nhầm lẫn, tôi chỉ không muốn đi vào chi tiết về cách foo đến được khác nhau dựa trên một constexpr, nhưng tôi hy vọng nó rõ ràng bây giờ. –