Skip to content

Last updated:2026-10-12

C++ Member Pointers and Type Information

::* — probably 99% of people have never used it, or even seen it; feel free to call it out in the comments! This section teaches the syntax from zero, then puts it to work with a real example from a project.

1. What Is ::*

C::* is the pointer-to-member syntax in C++; it denotes a pointer to a member of some class C. This syntax is used to point at a class's member variables or member functions. Unlike an ordinary pointer, a member pointer does not point at a concrete memory address of an object; it points at the location of a member within the class and must be used together with an object instance of that class.

1.1 Syntax

  • T C::* is a pointer to a member variable of type T inside class C.
  • R (C::*)(Args...) is a pointer to a member function of class C with return type R and parameter list Args....

1.2 Pointers to Member Variables

A pointer to a member variable points at a member variable of some class, using the form T C::*.

For example: the snippet below defines a member pointer ptr that points at the x member of the class MyClass. obj.*ptr accesses the object's member variable through the member pointer.

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 Pointers to Member Functions

A pointer to a member function points at a member function of a class, using the form R (C::*)(Args...).

Example: call the member function via obj.*funcPtr().

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

3. What Is It Good For?

Suppose you have an ORM framework that needs to obtain the field type from a member pointer in order to generate the corresponding column type; you could write:

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. A Practical Utility Derived from Real Projects!

In real projects, we can use C::* to extract the object type and the member type. How do we implement it?

The answer: templates + C::*

As in the example below, we can extract the corresponding member type and class type through value_type_from_member_pointer and class_type_from_member_pointer — a very convenient utility.

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;

Comments