コンテンツにスキップ

最終更新:2026-10-12

C++ メンバポインタと型情報

::* を使ったことがある、あるいは見たことさえある人は99%いないでしょう。心当たりがあればコメント欄に書いてください!本節では文法をゼロから解説し、実際のプロジェクトでの例を使ってこの使い方を実践します。

1.::* とは何か

C::* は C++ における**メンバポインタ**の構文で、あるクラス C のメンバへのポインタを表します。この構文は、クラスのメンバ変数やメンバ関数を指すのに使われます。通常のポインタとは異なり、メンバポインタはあるオブジェクトの具体的なメモリアドレスを指すのではなく、クラス内のメンバの**位置**を指し、クラスのオブジェクトインスタンスと一緒に使う必要があります。

1.1 構文

  • T C::* は、クラス C 内の型 T のメンバ変数へのポインタです。
  • R (C::*)(Args...) は、クラス C 内の、戻り値の型が R、引数リストが Args... のメンバ関数へのポインタです。

1.2 メンバ変数ポインタ

メンバ変数ポインタはあるクラスのメンバ変数を指し、T C::* という形式を使用します。

例:次の例では、MyClass クラスの x メンバを指すメンバポインタ ptr を定義しています。obj.*ptr はメンバポインタを通じてオブジェクトのメンバ変数にアクセスします。

struct MyClass {
    int x;
    double y;
};

int MyClass::*ptr = &MyClass::x;

MyClass obj;
obj.x = 10;
std::cout << "obj.x = " << obj.*ptr << std::endl;

1.3 メンバ関数ポインタ

メンバ関数ポインタはクラスのメンバ関数を指し、R (C::*)(Args...) という形式を使用します。

例:obj.*funcPtr() によってメンバ関数を呼び出します。

void (MyClass::*funcPtr)() const = &MyClass::print;
MyClass obj;
(obj.*funcPtr)();

3.何に使えるのか?

ORM フレームワークがあり、メンバポインタからフィールドの型を取得して、対応する列の型を生成する必要があるとします。次のように書けます:

struct User {
    std::string username;
    int user_id;
};

// 自动生成数据库列的定义
template <typename T, typename C>
void generate_sql_column(T C::*member_ptr, const std::string& column_name) {
    if constexpr (std::is_same_v<T, std::string>) {
        std::cout << column_name << " VARCHAR(255)" << std::endl;
    } else if constexpr (std::is_integral_v<T>) {
        std::cout << column_name << " INT" << std::endl;
    }
}

int main() {
    // 假设我们想自动为 User 类生成 SQL 表结构
    generate_sql_column(&User::username, "username");
    generate_sql_column(&User::user_id, "user_id");

    return 0;
}

4.実際のプロジェクトから派生した実用ツール!

実際のプロジェクトでは、C::* を使ってオブジェクトの型とメンバの型を抽出できます。どう実装するのでしょうか?

答えは、テンプレート + C::* です。

次の例のように、value_type_from_member_pointer と class_type_from_member_pointer を使って、対応するメンバの型とクラスの型を抽出できます。非常に便利なツールです。

template <typename T, typename C>
struct from_member_pointer_helper<T C::*> {
    using value_type = T;     
    using class_type = C;     
};

template <auto Ptr>
struct from_member_pointer : from_member_pointer_helper<typename std::remove_cvref_t<decltype(Ptr)>> {};

template <auto Ptr>
using value_type_from_member_pointer = from_member_pointer<Ptr>::value_type;

template <auto Ptr>
using class_type_from_member_pointer = from_member_pointer<Ptr>::class_type;

関連トピック

コメント