Date: Mon, 25 May 2020 15:14:55 +0300
Hello,
suppose you have following clases:
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);
> }
This will allow to call:
*user(real, &Real::inc);*
but will not allow to do
*user(real, &Mock::inc);*
However because of generic context, both calls must be possible.
Here is simple implementation of the feature:
#include <type_traits>
>
> 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)...);
> }
suppose you have following clases:
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);
> }
This will allow to call:
*user(real, &Real::inc);*
but will not allow to do
*user(real, &Mock::inc);*
However because of generic context, both calls must be possible.
Here is simple implementation of the feature:
#include <type_traits>
>
> 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)...);
> }
Received on 2020-05-25 07:18:37