Tôi có sau C++ 11 mã (phiên bản đơn giản):Khi nào một thành viên lớp constexpr tĩnh cần định nghĩa ngoài lớp?
struct Info
{
const char * name;
int version;
};
class Base
{
public:
const Info info;
Base (Info info) : info (info) {}
};
class Derived : public Base
{
public:
static constexpr Info info = {"Foobar", 2};
Derived() : Base (info) {}
};
int main()
{
static Derived derived;
return 0;
}
GCC 4.9.1 biên dịch và liên kết đang tốt này. Clang 3.5.0, mặt khác, than phiền về một tham chiếu không xác định:
/tmp/test-109c5c.o: In function `main':
test.cc:(.text+0x1c): undefined reference to `Derived::info'
test.cc:(.text+0x22): undefined reference to `Derived::info'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Điều gì đúng? Mã này có hợp pháp hay không? Sự hiểu biết của tôi về các quy tắc liên quan đến các thành viên constexpr tĩnh (chủ yếu dựa trên this question) là một định nghĩa out-of-class là cần thiết chỉ khi địa chỉ của biến được thực hiện. Nhưng tôi không lấy địa chỉ của Derived :: info hoặc sử dụng một tham chiếu đến nó ở bất cứ đâu; Tôi chỉ truyền nó theo giá trị cho hàm tạo Base.
cách giải quyết khác nhau mà tôi đã tìm thấy:
- Hãy cả nhà xây dựng (Base và nguồn gốc) constexpr. Điều này có thể hoặc không thể là một lựa chọn với các lớp thực, phức tạp hơn các lớp trong ví dụ. Tôi sẽ thử nó, anyway.
- Khai báo cá thể của Nguồn gốc có nguồn gốc tự động thay vì thời lượng tĩnh. Đây không phải là một tùy chọn cho dự án thực: lớp Derived là một thực thi plugin, và một thể hiện của nó cần được xuất khẩu như một biểu tượng công khai trong một đối tượng được chia sẻ.
- Xóa nguồn gốc :: thông tin hoàn toàn và gọi hàm tạo cơ sở bằng đối tượng tạm thời được khởi tạo cú đúp thay vào đó, tức là
Base ({"Foobar", 2})
. Giải pháp này sẽ làm việc, nhưng nó xấu xí (theo ý kiến của tôi) khi các thành viên được thêm vào struct Info.
Bản sao có thể có của [vector :: push_back odr-sử dụng giá trị, khiến tham chiếu không xác định đối với thành viên lớp tĩnh] (http://stackoverflow.com/questions/272900/undefined-reference-to-static-class-member) –
Điều gì về việc làm cho nó thành một chức năng thành viên thay vì thành viên dữ liệu? – imreal
@ πάνταῥεῖ Tôi không sử dụng std :: vector, nhưng liên kết của bạn đưa tôi đi đúng hướng. Cảm ơn! –