Tôi biết có rất nhiều câu hỏi tương tự, nhưng bằng một số câu hỏi khác nhau. Đó là về tình huống sau:Chỉ định thành viên lớp constexpr tĩnh cho biến thời gian chạy
#include <iostream>
#include <array>
template<typename T> class MyClass
{
public:
static constexpr std::array<T,4> ARRAY {{4, 3, 1, 5}};
};
int main()
{
constexpr std::array<int, 4> my_array(MyClass<int>::ARRAY); // works fine -> can use the ARRAY to initialize constexpr std::array
constexpr int VALUE = 5*MyClass<int>::ARRAY[0]; // works also fine
int value;
value = my_array[0]; // can assign from constexpr
value = MyClass<int>::ARRAY[0]; // undefined reference to `MyClass<int>::ARRAY
std::cout << VALUE << std::endl;
std::cout << value << std::endl;
return 0;
}
Theo như tôi hiểu constexpr
là các hằng số biên dịch. Vì vậy, trình biên dịch có thể thực hiện một số phép tính, ví dụ để tính toán VALUE
. Ngoài ra tôi rõ ràng có thể xác định một constexpr std::array<,>
, từ đó tôi có thể gán các giá trị cho các biến thời gian chạy. Tôi hy vọng trình biên dịch sẽ đặt value = 4
vào chương trình thực thi, để tránh hoạt động tải. Tuy nhiên, tôi không thể gán trực tiếp từ các thành viên tĩnh, nhận được lỗi
undefined reference to `MyClass<int>::ARRAY'
clang-3.7: error: linker command failed with exit code 1
mà làm cho không có ý nghĩa với tôi, bởi vì nó có thể được thực hiện với một bước trung gian của một biến khác constexpr
.
Vì vậy, câu hỏi của tôi là: Tại sao một thành viên constexpr tĩnh của một lớp không được gán cho một biến thời gian chạy?
Lưu ý: Trong MWE của tôi, lớp là lớp mẫu, không ảnh hưởng đến lỗi. Tuy nhiên, ban đầu tôi quan tâm đến trường hợp cụ thể này, điều mà tôi mong đợi là tổng quát hơn đối với một lớp không phải mẫu.
(Compiler là clang++
hoặc g++
với -std=c++11
- họ cung cấp cho các lỗi tương tự)
Edit: @Bryan Chen: Quên các dòng đầu ra. Được thêm ngay bây giờ.
'clang ++' có vấn đề này: http://coliru.stacked-crooked.com/a/e9698f2bb249e509. Nhưng 'g ++' hoạt động: http://coliru.stacked-crooked.com/a/5ef23fe29b0aaa28. Lỗi Clang? –
VS2015 nói điều này: 'khởi tạo trong lớp cho loại 'const std :: mảng' chưa được triển khai; thành viên tĩnh sẽ vẫn chưa được khởi tạo trong thời gian chạy nhưng sử dụng trong các biểu thức hằng số được hỗ trợ'. Bạn có thể đang chạy vào một cái gì đó tương tự. –
@Bryan: Tôi đã không chắc chắn. Tôi đã cài đặt g ++ 4.8.5, chưa hỗ trợ C++ 14. Nhưng tôi mong đợi điều này để làm việc đã cho C++ 11 !? – marlam