Getting the type of a member

廉价感情. 提交于 2019-12-05 14:11:18

问题


NOTE: This question was originally asked way back in 2012. Before the decltype specifier was fully implemented by any major compilers. You should not be looking at this code unless you only have access to C++03. All major C++11 compliant compilers now support decltype.

Is there an easy way to retrieve the type of a member?
In 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);

}

I am actually doing this (ie being slightly lazy):

#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;

But rather than have to force the user to specify the type of the member I want to the compiler to generate it pragmatically.

#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;

回答1:


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

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

Is the C++11 way. It requires you to use &Person::age instead of Person::age, although you could easily adjust the macro to make the ampersand implicit.




回答2:


In C++2003 it can't be done directly but you can delegate to a function template which deduces the type:

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

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



回答3:


Since in your examples you use boost I'd use TYPEOF from boost.

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

it works very similarly to decltype of C++11.

http://en.wikipedia.org/wiki/C%2B%2B11#Type_inference in your case:

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

you can compare the types decltype or BOOST_TYPEOF gives you with typeinfo

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

you need to make a proper people vector with length >14 for the example to work.

gcc has typeof or typeof doing the same thing.

As a side note. For the example you gave you could just define the types in the struct instead if none of the above is relevant for you.

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

then use std::vector< Person::agetype > ages;



来源:https://stackoverflow.com/questions/8866194/getting-the-type-of-a-member

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!