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

3 に答える 3

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

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

C++11 の方法です。アンパサンドを暗黙的にするためにマクロを簡単に調整できますが、&Person::age代わりにを使用する必要があります。Person::age

于 2012-01-14T23:21:23.840 に答える
6

C++2003 では直接行うことはできませんが、型を推測する関数テンプレートに委譲できます。

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

int main() {
    deduce_member_type(&Person::age);
}
于 2012-01-14T23:34:45.057 に答える
1

あなたの例ではブーストを使用しているので、ブーストから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< Person::agetype > ages を使用します。

于 2012-01-14T23:42:13.420 に答える