Vấn đề ngôn ngữ lạ là CWG 1581 :
Điều 15 [đặc biệt] hoàn toàn rõ ràng rằng các hàm thành viên đặc biệt chỉ được định nghĩa ngầm khi chúng được sử dụng odr. Điều này tạo ra một vấn đề cho các biểu thức không đổi trong bối cảnh không được đánh giá:
struct duration {
constexpr duration() {}
constexpr operator int() const { return 0; }
};
// duration d = duration(); // #1
int n = sizeof(short{duration(duration())});
Vấn đề ở đây là chúng tôi không được phép định nghĩa ngầm constexpr duration::duration(duration&&)
trong chương trình này, vì vậy biểu thức trong danh sách khởi tạo không phải là biểu thức không đổi (vì nó gọi hàm constexpr chưa được xác định), do đó, trình khởi tạo giằng có chứa một chuyển đổi thu hẹp , vì vậy chương trình không thành hình.
Nếu chúng tôi bỏ dòng số 1, hàm tạo di chuyển được xác định ngầm định và chương trình hợp lệ. Hành động ma quái này ở một khoảng cách là vô cùng đáng tiếc. Triển khai phân kỳ về điểm này.
Bạn có thể đọc phần còn lại của mô tả vấn đề.
Một giải pháp cho vấn đề này đã được thông qua trong P0859 tại Albuquerque vào năm 2017 (sau khi C ++ 17 xuất xưởng). Vấn đề đó là một trình chặn cho cả hai có thể có constexpr std::swap
(được giải quyết trong P0879 ) và constexpr std::invoke
(được giải quyết trong P1065 , cũng có ví dụ CWG1581), cho cả C ++ 20.
Ví dụ đơn giản nhất để hiểu ở đây, theo tôi, là mã từ báo cáo lỗi LLVM được chỉ ra trong P1065:
template<typename T>
int f(T x)
{
return x.get();
}
template<typename T>
constexpr int g(T x)
{
return x.get();
}
int main() {
// O.K. The body of `f' is not required.
decltype(f(0)) a;
// Seems to instantiate the body of `g'
// and results in an error.
decltype(g(0)) b;
return 0;
}
CWG1581 là tất cả về khi các chức năng thành viên constexpr được xác định và độ phân giải đảm bảo rằng chúng chỉ được xác định khi sử dụng. Sau P0859, ở trên được hình thành tốt (loại b
là int
).
Vì std::swap
và std::invoke
cả hai đều phải dựa vào việc kiểm tra các chức năng thành viên (di chuyển xây dựng / chuyển nhượng trong cuộc gọi trước và cuộc gọi điều hành / thay thế cuộc gọi sau), cả hai đều phụ thuộc vào việc giải quyết vấn đề này.