【问题标题】:What is this member pointer syntax?这个成员指针语法是什么?
【发布时间】:2022-06-14 15:47:03
【问题描述】:
#include <iostream>
#include <type_traits>

struct Foo
{
    // ### Member Function ###
    void bar() { std::cout << "Foo::bar()\n"; }
};

// ### 1 Parameter Primary Template (which is empty) ###
template<typename>
struct Traits {};

// ### 2 Parameter Template Specialization ###
template<class T, class U>
struct Traits<T U::*>
              ^^^^^^ // I don't understand this syntax
{
    using type1 = T;
    using type2 = U;
};

int main()
{
    // ### Pointer to member function ###
    void (Foo::*memFuncPtr)() = &Foo::bar;
    
    Foo f;

    // ### Use the member function pointer to invoke it ###
    (f.*memFuncPtr)();
    
    static_assert(std::is_same_v<void(), Traits<decltype(&Foo::bar)>::type1>);
    static_assert(std::is_same_v<Foo, Traits<decltype(&Foo::bar)>::type2>);

    return 0;
}

专业化语法是如何工作的? U::* 中的UFoo 类型相同是有道理的,但为什么Tvoid() 类型相同?

编辑

在 @user17732522 非常有用的 cmets 和 @AnoopRana 的回答之后,我能够更改 main 函数实现以使用相同的语法(只是为了看到它工作)。

int main()
{
    using F = void();

    // ### Pointer to member function ###
    F Foo::*memFuncPtr = &Foo::bar;

    Foo f;

    // ### Use the member function pointer to invoke it ###
    (f.*memFuncPtr)();

    static_assert(std::is_same_v<void(), Traits<decltype(&Foo::bar)>::type1>);
    static_assert(std::is_same_v<Foo, Traits<decltype(&Foo::bar)>::type2>);

    return 0;
}

【问题讨论】:

  • 因为Foo::bar 的类型为void()?
  • @Elliott Foo::bar 函数的返回类型是voidT 不是void T 实际上是void()。跨度>
  • @JamesAdkison 类型别名通常不能简单地替换为文本。这与通常的函数指针相同,例如给定using T = void();T* 类型是指向void() 函数的指针,尽管没有别名的语法是void(*)()。额外的修饰符需要在语义上应用于别名类型。
  • 我将我的评论作为一个上帝链接:godbolt.org/z/Prbca5PYK 尽管@user17732522 可能已经回答了它(一旦我明白他们所说的话!)
  • 只是T U::*的意思是“指向T类型的U类成员的指针”,这里Tvoid()。没有T 的声明语法是void (U::*)() 并不重要。

标签: c++


【解决方案1】:
struct Trait<T U::*>
             ^^^^^^ // I don't understand this syntax

上述语法意味着我们有一个指向名为U 的类成员的指针,其中该成员的类型为T。换句话说,一个指向类U 的成员的指针,它的类型为T

现在让我们将其应用于&amp;Foo::bar。表达式&amp;Foo::bar 的类型是:

void (Foo::* f)()

现在您可以将其与 T U::* 进行比较

所以,经过比较我们得到:

  1. U = Foo类类型
  2. T = void() 表示返回类型为void 且不带参数的函数,即函数类型

这实际上意味着我们有一个指向成员函数的指针,该成员函数的返回类型为 void,并且不带任何参数,属于 Foo 类。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-04
    • 1970-01-01
    • 2016-05-15
    • 2018-10-27
    • 1970-01-01
    • 1970-01-01
    • 2010-12-15
    • 2016-12-27
    相关资源
    最近更新 更多