C++ 指向模板上下文中的成员函数或静态函数的指针
我在泛型上下文中使用指向成员函数的指针,它工作正常C++ 指向模板上下文中的成员函数或静态函数的指针,c++,templates,c++17,function-pointers,C++,Templates,C++17,Function Pointers,我在泛型上下文中使用指向成员函数的指针,它工作正常 struct Mock{ static int inc(int){ return 0; } static int dec(int){ return 0; } }; struct Real{ Real(int v) : v(v){} int inc(int a) const{ return a + v; } int dec(in
struct Mock{
static int inc(int){
return 0;
}
static int dec(int){
return 0;
}
};
struct Real{
Real(int v) : v(v){}
int inc(int a) const{
return a + v;
}
int dec(int a) const{
return a - v;
}
private:
int v;
};
template<typename C, typename F>
auto user(C &c, F func){
return (c.*func)(5);
}
int main(){
Real real(5);
return user(real, &Real::inc);
}
我正在使用C++17。和重载和SFINAE:
template<typename C, typename F>
auto user(C& c, F func) -> decltype((c.*func)(5)) {
return (c.*func)(5);
}
template<typename C, typename F>
auto user(C&, F func) -> decltype(func(5)) {
return func(5);
}
带过载和SFINAE:
template<typename C, typename F>
auto user(C& c, F func) -> decltype((c.*func)(5)) {
return (c.*func)(5);
}
template<typename C, typename F>
auto user(C&, F func) -> decltype(func(5)) {
return func(5);
}
可用于检测指向成员的指针。然后,您可以执行一个简单的if constexpr
来改变这些参数和只接受参数的可调用参数之间的行为
template<typename C, typename F>
auto user(C &c, F func){
if constexpr (std::is_member_pointer_v<F>)
return (c.*func)(5);
else
return func(5);
}
然后你可以简单地使用
模板
自动用户(C&C、F func){
返回std::invoke(func,c,5);
}
可用于检测指向成员的指针。然后,您可以执行一个简单的if constexpr
来改变这些参数和只接受参数的可调用参数之间的行为
template<typename C, typename F>
auto user(C &c, F func){
if constexpr (std::is_member_pointer_v<F>)
return (c.*func)(5);
else
return func(5);
}
然后你可以简单地使用
模板
自动用户(C&C、F func){
返回std::invoke(func,c,5);
}
我的5美分
这是我在读了@StoryTeller answer之后得出的结论:
#include <type_traits>
#include <functional>
namespace class_invoke_impl_{
template <class T, class F, class... Args>
constexpr auto class_invoke_(T &&cl, F func, std::true_type, Args&&... args){
return (std::forward<T>(cl).*func)(std::forward<Args>(args)...);
}
template <class T, class F, class... Args>
constexpr auto class_invoke_(T const &, F func, std::false_type, Args&&... args){
return func(std::forward<Args>(args)...);
}
}
template <class T, class F, class... Args>
constexpr auto class_invoke(T &&cl, F func, Args&&... args){
using namespace class_invoke_impl_;
return class_invoke_(std::forward<T>(cl), func, std::is_member_pointer<F>{}, std::forward<Args>(args)...);
}
#包括
#包括
命名空间类\u invoke\u impl_{
模板
constexpr自动类调用(T&&cl,F func,std::true_type,Args&&…Args){
返回(std::forward(cl)。*func)(std::forward(args)…);
}
模板
constexpr自动类调用(T const&,F func,std::false_type,Args&&…Args){
返回函数(std::forward(args)…);
}
}
模板
constexpr自动类调用(T&&cl,F func,Args&&…Args){
使用名称空间类\u invoke\u impl;
返回类调用(std::forward(cl),func,std::is_member_pointer{},std::forward(args)…);
}
我的5美分
这是我在读了@StoryTeller answer之后得出的结论:
#include <type_traits>
#include <functional>
namespace class_invoke_impl_{
template <class T, class F, class... Args>
constexpr auto class_invoke_(T &&cl, F func, std::true_type, Args&&... args){
return (std::forward<T>(cl).*func)(std::forward<Args>(args)...);
}
template <class T, class F, class... Args>
constexpr auto class_invoke_(T const &, F func, std::false_type, Args&&... args){
return func(std::forward<Args>(args)...);
}
}
template <class T, class F, class... Args>
constexpr auto class_invoke(T &&cl, F func, Args&&... args){
using namespace class_invoke_impl_;
return class_invoke_(std::forward<T>(cl), func, std::is_member_pointer<F>{}, std::forward<Args>(args)...);
}
#包括
#包括
命名空间类\u invoke\u impl_{
模板
constexpr自动类调用(T&&cl,F func,std::true_type,Args&&…Args){
返回(std::forward(cl)。*func)(std::forward(args)…);
}
模板
constexpr自动类调用(T const&,F func,std::false_type,Args&&…Args){
返回函数(std::forward(args)…);
}
}
模板
constexpr自动类调用(T&&cl,F func,Args&&…Args){
使用名称空间类\u invoke\u impl;
返回类调用(std::forward(cl),func,std::is_member_pointer{},std::forward(args)…);
}
谢谢。重构是不可能的,因为它需要类似于普通的类,但这是一种有趣的方法thinking@Nick-它需要类似于普通类-但您已经违反了这一点,将函数设置为静态。谢谢。重构是不可能的,因为它需要类似于普通的类,但这是一种有趣的方法thinking@Nick-它需要类似于普通类-但您已经违反了这一点,将函数设置为静态。为什么在其他函数中使用静态断言?无论如何它都会失败?@Nick:我更喜欢在那里出错,而不是在std::invoke
的内部机制中。为什么在else中有静态断言?无论如何它都会失败?@Nick:我宁愿在那里出错,而不是在std::invoke
的内部机制中。
#include <type_traits>
#include <functional>
namespace class_invoke_impl_{
template <class T, class F, class... Args>
constexpr auto class_invoke_(T &&cl, F func, std::true_type, Args&&... args){
return (std::forward<T>(cl).*func)(std::forward<Args>(args)...);
}
template <class T, class F, class... Args>
constexpr auto class_invoke_(T const &, F func, std::false_type, Args&&... args){
return func(std::forward<Args>(args)...);
}
}
template <class T, class F, class... Args>
constexpr auto class_invoke(T &&cl, F func, Args&&... args){
using namespace class_invoke_impl_;
return class_invoke_(std::forward<T>(cl), func, std::is_member_pointer<F>{}, std::forward<Args>(args)...);
}