Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 指向模板上下文中的成员函数或静态函数的指针_C++_Templates_C++17_Function Pointers - Fatal编程技术网

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)...);
}