【发布时间】: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::* 中的U 与Foo 类型相同是有道理的,但为什么T 与void() 类型相同?
编辑
在 @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函数的返回类型是void但T不是voidT实际上是void()。跨度> -
@JamesAdkison 类型别名通常不能简单地替换为文本。这与通常的函数指针相同,例如给定
using T = void();,T*类型是指向void()函数的指针,尽管没有别名的语法是void(*)()。额外的修饰符需要在语义上应用于别名类型。 -
我将我的评论作为一个上帝链接:godbolt.org/z/Prbca5PYK 尽管@user17732522 可能已经回答了它(一旦我明白他们所说的话!)
-
只是
T U::*的意思是“指向T类型的U类成员的指针”,这里T是void()。没有T的声明语法是void (U::*)()并不重要。
标签: c++