这个成员函数选择代码可以不写std::invoke吗?
Can this member function selection code be written without std::invoke?
我试图 select 一个成员 fn
基于一些 constexpr
值。然后我尝试调用 selected 函数,但我收到关于如何使用不正确语法调用成员 fn
的错误。
error: must use '.*' or '->*' to call pointer-to-member function in
'S::SelectedGetter<&S::fn1, &S::fn2>::fn (...)', e.g. '(... ->*
S::SelectedGetter<&S::fn1, &S::fn2>::fn) (...)'
18 | return SelectedGetter<&S::fn1, &S::fn2>::fn();
我试图“恰当地”称呼它但失败了。最后我使用 std::invoke
,但我想知道是否可以在没有 std::invoke
的情况下仅使用“原始”C++ 语法来完成此操作。
#include <algorithm>
#include <type_traits>
static constexpr int number = 18;
struct S
{
using GetterFn = uint32_t(S::*)() const;
uint32_t fn1()const {
return 47;
}
uint32_t fn2() const {
return 8472;
}
template <GetterFn Getter1, GetterFn Getter2>
struct SelectedGetter
{
static constexpr GetterFn fn = (number < 11) ? Getter1 : Getter2;
};
uint32_t f() {
return std::invoke((SelectedGetter<&S::fn1, &S::fn2>::fn), this);
}
};
int main()
{
return S{}.f() % 100;
}
注意:我对 C++20 解决方案没问题,例如,如果某些 concept
魔法可以帮助...
你可以这样称呼它 normal member function pointer call。
正确的语法是
return ((*this).*SelectedGetter<&S::fn1, &S::fn2>::fn)();
或
return (this->*SelectedGetter<&S::fn1, &S::fn2>::fn)();
旁注:
- 如果你在
f
中调用的函数是const
,你也可以把它也uint32_t f() const
- 其次,您可以将
SelectedGetter
替换为 variable template (since c++14),现在您需要 less-typing
看起来像
// variable template
template<GetterFn Getter1, GetterFn Getter2>
static constexpr auto fn = (number < 11) ? Getter1 : Getter2;
uint32_t f() const {
return (this->*fn<&S::fn1, &S::fn2>)();
}
我试图 select 一个成员 fn
基于一些 constexpr
值。然后我尝试调用 selected 函数,但我收到关于如何使用不正确语法调用成员 fn
的错误。
error: must use '.*' or '->*' to call pointer-to-member function in
'S::SelectedGetter<&S::fn1, &S::fn2>::fn (...)', e.g. '(... ->*
S::SelectedGetter<&S::fn1, &S::fn2>::fn) (...)'
18 | return SelectedGetter<&S::fn1, &S::fn2>::fn();
我试图“恰当地”称呼它但失败了。最后我使用 std::invoke
,但我想知道是否可以在没有 std::invoke
的情况下仅使用“原始”C++ 语法来完成此操作。
#include <algorithm>
#include <type_traits>
static constexpr int number = 18;
struct S
{
using GetterFn = uint32_t(S::*)() const;
uint32_t fn1()const {
return 47;
}
uint32_t fn2() const {
return 8472;
}
template <GetterFn Getter1, GetterFn Getter2>
struct SelectedGetter
{
static constexpr GetterFn fn = (number < 11) ? Getter1 : Getter2;
};
uint32_t f() {
return std::invoke((SelectedGetter<&S::fn1, &S::fn2>::fn), this);
}
};
int main()
{
return S{}.f() % 100;
}
注意:我对 C++20 解决方案没问题,例如,如果某些 concept
魔法可以帮助...
你可以这样称呼它 normal member function pointer call。 正确的语法是
return ((*this).*SelectedGetter<&S::fn1, &S::fn2>::fn)();
或
return (this->*SelectedGetter<&S::fn1, &S::fn2>::fn)();
旁注:
- 如果你在
f
中调用的函数是const
,你也可以把它也uint32_t f() const
- 其次,您可以将
SelectedGetter
替换为 variable template (since c++14),现在您需要 less-typing
看起来像
// variable template
template<GetterFn Getter1, GetterFn Getter2>
static constexpr auto fn = (number < 11) ? Getter1 : Getter2;
uint32_t f() const {
return (this->*fn<&S::fn1, &S::fn2>)();
}