2016-04-19 9 views
1

構造体メンバに対して決定された操作を適用し、そのメンバをパラメータとして渡すことができる汎用メソッドを実装したいと思います。指定された構造体メンバに操作を適用する一般的な方法

typedef struct Type_t{ 
    int a; 
    double b; 
} Type; 

void gen_method(Type &t, TypeMember m){ 
    t.m += 1; 
} 

私が今まで行ってきた:

typedef struct Type_t{ 
    int a; 
    double b; 
} Type; 

typedef double Type::* PointerToTypeMemberDouble; 

void gen_method(Type &t, PointerToTypeMemberDouble member){ 
    t.*member += 1; 
} 

私は

を何をしたいのか今私が同じジェネリックメソッドを実装したいができるように、テンプレートを使用して、このような何かその型とは独立して、どの構造体メンバにもアクセスすることができます。これは私がテストしたものです:

typedef struct Type_t{ 
    int a; 
    double b; 
} Type; 

template<typename T> 
struct PointerToTypeMember{ 
    typedef T Type::* type; 
}; 

template<typename T> 
void gen_method(Type &t, PointerToTypeMember<T>::type member){ 
    // ... 
} 

エラー

私がコンパイルしようとすると、私はこのエラーのリストを得る: error C2061: syntax error : identifier 'type'

そして、この警告: warning C4346: 'myNamesPace::Type<T>::type' : dependent name is not a type

答えて

3

はまず、あなたのエラーのために、あなたはtypenameを指定する必要があります。

template<typename T> 
void gen_method(Type &t, typename PointerToTypeMember<T>::type member) { 

は第二に、あなたがすべてでヘルパークラステンプレートPointerToTypeMemberを必要としないWhere and why do I have to put the “template” and “typename” keywords?

を参照してください。

Type t{}; 
gen_method<int>(t, &Type::a); 
gen_method<double>(t, &Type::b); 

あなたは、直接テンプレートパラメータとして

template<typename T> 
void gen_method(Type &t, T Type::*member){ 
    t.*member += 1; 
} 

とテンプレート引数を指定する必要はありませんが、クラスのメンバを指定することができます。そしてnested-name-specifier couldn't be deduced in template argument deductionので、あなたはとしてそれを使用するときにテンプレート引数を指定する必要がありますテンプレート引数の控除がそれを行います。

Type t{}; 
gen_method(t, &Type::a); 
gen_method(t, &Type::b); 
+2

サンプルではメンバータイプを推測できますが、OPでは 'gen_method'コールでメンバータイプを指定する必要があることに注意してください。 – Jarod42

0

I問題を発見した。

template<typename T> 
void gen_method(Type &t, typename PointerToTypeMember<T>::type member){ 
    // ... 
} 

問題は、私はPointerToTypeMember<T>::typetypenameキーワードを使用したタイプであるコンパイラに指示しなければならないことでした。