【问题标题】:Getting the type of a member获取成员的类型
【发布时间】:2012-02-10 13:53:17
【问题描述】:

注意:这个问题最初是在 2012 年提出的。在任何主要编译器完全实现 decltype 说明符之前。除非您只能访问 C++03,否则您不应查看此代码。所有主要的 C++11 兼容编译器现在都支持decltype

有没有一种简单的方法来检索成员的类型?
在 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);

}

我实际上正在这样做(即有点懒惰):

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

但我不必强制用户指定成员的类型,而是让编译器务实地生成它。

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

【问题讨论】:

  • 如果没有Person 的实例,我认为C++ 甚至不能让你谈论Person::age
  • @SethCarnegie:如果这是真的(我认为可能是),那就有点烦人了。如何发现Person::age 的大小?
  • 创建类似typedef int Person::age_t; 的东西怎么样?
  • sizeof 没有实例。试试看:sizeof(reinterpret_cast&lt;Person*&gt;(0) -&gt; age)@SethCarnegie 我误解了这个问题吗?
  • @AaronMcDaid 我今天在使用offsetof 时也想到了这一点。不过更喜欢 MSN 的答案,因为 offsetof 方式具有未定义的行为

标签: c++ templates template-meta-programming c++03


【解决方案1】:
template <class T, class M> M get_member_type(M T:: *);

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

是C++11的方式。它要求您使用&amp;Person::age 而不是Person::age,尽管您可以轻松调整宏以使与符号隐含。

【讨论】:

  • 哇,它有效...但我不明白。 &amp;Person::age 是如何变成age 的类型,但是将&amp;Person::age 应用到M T:: * 上? M T:: * 是什么意思?
  • 另见C++ typename of member variable,它建议在C++11 中使用decltype 就像decltype(Person::age) 一样简单。
【解决方案2】:

在 C++2003 中不能直接完成,但您可以委托给推断类型的函数模板:

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

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

【讨论】:

  • 同样的问题,至于接受的答案:T S::* member 是什么声明?我不明白,&amp;Person::age 如何应用于T S::* member
  • @j00hi:它是一个指向成员的指针(变量)。类型由包含成员的类型和成员类型组成。指向成员的正常使用是使用 .*-&gt;* 运算符。
【解决方案3】:

因为在你的例子中你使用了 boost,所以我会使用 boost 中的 TYPEOF。

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

它的工作方式与 C++11 的 decltype 非常相似。

http://en.wikipedia.org/wiki/C%2B%2B11#Type_inference 在你的情况下:

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

您可以将 decltype 或 BOOST_TYPEOF 提供给您的类型与 typeinfo 进行比较

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

您需要制作一个长度 >14 的适当人员向量才能使示例正常工作。

gcc 有 typeof 或 typeof 做同样的事情。

作为旁注。对于您提供的示例,如果以上都与您无关,则可以只定义结构中的类型。

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

然后使用 std::vector 年龄;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-15
    • 2018-10-01
    • 2014-05-14
    • 1970-01-01
    • 2018-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多