考虑引用和常量的可变函数包装器

问题描述 投票:2回答:2

我创建了一个小函数包装器示例。我想让包装器考虑被调用的函数是否使用(const)引用,这意味着输出将是4/5而不是4/4,但是如果包装函数没有,我不想强​​制引用使用它们。

#include <iostream>
#include <string>

struct a {
  static void run(int cref) {
    cref = 5;
  };
};

struct b {
  static void run(int &cref) {
    cref = 5;
  };
};

template <class FTor>
struct foo {
    template <class ... Args>
    static void wrapper(Args ... args) {
      FTor::run(args ...);
    }
};


int main()
{
    int bar = 4;
    foo<a>::wrapper(bar);
    std::cout << bar;

    foo<b>::wrapper(bar);
    std::cout << bar;
}
c++ templates variadic-templates
2个回答
3
投票

那么使用完美转发怎么样?

template <class FTor>
struct foo {
    template <class ... Args>
    static void wrapper(Args && ... args) {
      FTor::run(std::forward<Args>(args) ...);
    }
};

这样,无论参数对输入的ref-qualification是什么,都会传递给内部函数。


1
投票

这是一个尝试回答可能是我对OP请求的误解,因为简单的完美转发解决了所描述的场景,而没有求助于包装函数参数的类型推导。

原始答案:至少对于您正在呈现的受限用例,您可以使用小型特征结构来推断从仿函数的参数类型传递给wrapper()的单个参数的类型:

#include <iostream>
#include <string>

struct a {
  static void run(int cref) {
    cref = 5;
  };
};

struct b {
  static void run(int &cref) {
    cref = 5;
  };
};

template <typename>
struct ArgType;

template <typename R, typename A>
struct ArgType<R(A)>
{ using type = A; };

template <class FTor>
struct foo {
    static void wrapper(typename ArgType<decltype(FTor::run)>::type args) {
      FTor::run(args);
    }
};

int main()
{
    int bar = 4;
    foo<a>::wrapper(bar);
    std::cout << bar;

    foo<b>::wrapper(bar);
    std::cout << bar;
}

输出:

45

请注意,这不支持包装器内的完美转发,因为wrapper()本身不是*类型推理上下文的一部分 - 而不是你的片段,它推断但不是基于你想要推断的内容。我希望有时间为变量函数模板添加一个通用解决方案,例如在你的代码片段中,包括完美转发。

© www.soinside.com 2019 - 2024. All rights reserved.