2012-01-14 45 views
10

LƯU Ý: Câu hỏi này ban đầu được hỏi cách quay lại vào năm 2012. Trước khi trình phân tích decltype được thực hiện đầy đủ bởi bất kỳ trình biên dịch chính nào. Bạn không nên xem mã này trừ khi bạn chỉ có quyền truy cập vào C++ 03. Tất cả các trình biên dịch C++ 11 chính hiện nay đều hỗ trợ decltype.Nhận loại thành viên

Có cách nào dễ dàng để truy xuất loại thành viên không?
Trong C++ 03

struct Person 
{ 
    std::string name; 
    int   age; 
    double  salary; 
}; 

int main() 
{ 
    std::vector<Person>  people; // get a vector of people. 

    std::vector<GET_TYPE_OF(Person::age)> ages; 

    ages.push_back(people[0].age); 
    ages.push_back(people[10].age); 
    ages.push_back(people[13].age); 

} 

Tôi đang thực sự làm điều này (tức là hơi lười biếng):

#define BuildType(className, member, type)         \ 
     struct className ## member: TypeBase<className, type>    \ 
     {                 \ 
      className ## member()           \ 
       : TypeBase<className, type>(#member, &className::member) \ 
      {}                \ 
     } 

BuildType(Person, name,  std::string); 
BuildType(Person, age,  int); 
BuildType(Person, salary, double); 
typedef boost::mpl::vector<Personname, Personage, Personsalary> FunckyMTPMap; 

Nhưng thay vì phải buộc người dùng phải xác định loại của các thành viên Tôi muốn để trình biên dịch tạo ra nó một cách thực dụng.

#define BuildType(className, member)             \ 
struct className ## member: TypeBase<className, TYPE_OF(className ## member)>   \ 
{                      \ 
    className ## member()                \ 
     : TypeBase<className, TYPE_OF(className ## member)>(#member, &className::member)\ 
    {}                     \ 
} 
BuildType(Person, name); 
BuildType(Person, age); 
BuildType(Person, salary); 
typedef boost::mpl::vector<Personname, Personage, Personsalary> FunckyMTPMap; 
+0

Tôi không nghĩ C++ cho phép bạn thậm chí nói về 'Person :: age' mà không có một cá thể' Person' –

+0

@SethCarnegie: Nếu đó là sự thật (và tôi nghĩ nó có thể), nó hơi khó chịu. Làm cách nào để khám phá ra kích thước của 'Person :: age'? –

+0

những gì về việc tạo ra một cái gì đó giống như một 'typedef int Person :: age_t;'? – greatwolf

Trả lời

9
template <class T, class M> M get_member_type(M T:: *); 

#define GET_TYPE_OF(mem) decltype(get_member_type(mem)) 

Liệu sản phẩm C++ 11 chiều. Nó yêu cầu bạn sử dụng &Person::age thay vì Person::age, mặc dù bạn có thể dễ dàng điều chỉnh macro để tạo ký hiệu và dấu.

+0

Ngọt ngào, điều này làm việc (đối với tôi ít nhất) –

5

Trong C++ 2003 nó không thể được thực hiện trực tiếp nhưng bạn có thể uỷ thác cho một mẫu chức năng mà suy luận kiểu:

template <typename T, typename S> 
void deduce_member_type(T S::* member) { 
    ... 
} 

int main() { 
    deduce_member_type(&Person::age); 
} 
1

Vì trong ví dụ của bạn, bạn sử dụng tăng Tôi muốn sử dụng typeof từ tăng .

http://www.boost.org/doc/libs/1_35_0/doc/html/typeof.html

nó hoạt động rất giống với decltype của C++ 11.

http://en.wikipedia.org/wiki/C%2B%2B11#Type_inference trong trường hợp của bạn:

std::vector<BOOST_TYPEOF(Person::age) > ages; 

bạn có thể so sánh các loại decltype hoặc BOOST_TYPEOF cung cấp cho bạn với typeinfo

#include <typeinfo> 
cout << typeid(obj).name() << endl; 

bạn cần phải thực hiện một dân tộc vector thích hợp với chiều dài> 14 cho ví dụ để làm việc.

gcc có loại hoặc typeof làm tương tự.

Như một lưu ý phụ. Đối với ví dụ bạn đã cho bạn chỉ có thể xác định các loại trong cấu trúc thay vì nếu không có điều nào ở trên phù hợp với bạn.

struct Person 
{ 
    typedef int agetype; 
    std::string name; 
    agetype   age; 
    int   salary; 
}; 

sau đó sử dụng std :: vector < Person :: agetype> ages;

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