Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.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++ 从std::tuple提取方法签名的类型_C++_C++17_Template Meta Programming_Stdtuple_Parameter Pack - Fatal编程技术网

C++ 从std::tuple提取方法签名的类型

C++ 从std::tuple提取方法签名的类型,c++,c++17,template-meta-programming,stdtuple,parameter-pack,C++,C++17,Template Meta Programming,Stdtuple,Parameter Pack,我正在寻找一种方法来提取std::tuple的类型来定义方法签名。以以下(人为的)例子: 模板 甲级 { 公众: 类型def RetT ReturnType; typedef std::元组ArgTypes; 回收剂量测定法(ArgsT…args) { //没有什么意义,但这只是一个例子 返回(RetT)printf(args…); } }; 模板 A级适配器; //只需按原样传递参数即可 模板 类AAdapter、RetT、ArgsT…>:public A{}; //如果RetT是float,

我正在寻找一种方法来提取
std::tuple
的类型来定义方法签名。以以下(人为的)例子:

模板
甲级
{
公众:
类型def RetT ReturnType;
typedef std::元组ArgTypes;
回收剂量测定法(ArgsT…args)
{
//没有什么意义,但这只是一个例子
返回(RetT)printf(args…);
}
};
模板
A级适配器;
//只需按原样传递参数即可
模板
类AAdapter、RetT、ArgsT…>:public A{};
//如果RetT是float,则添加额外的第一个参数
模板
A级适配器:公共A{};
模板
B类
{
公众:
类型定义A适配器A适配器;
//这需要与aaAdapter::doSomething()具有相同的方法签名(返回类型和参数类型)
模板
typename AAdapter::ReturnType doSomething(
typename std::tuple_元素::type…args
) {
返回a.doSomething(参数…);
}
公众:
a适配器a;
};
int main(int argc,字符**argv)
{
//我希望能够删除和下面的。
B b1;
b1.剂量测量(“两个值:%d,%d\n”,1,2);
B b2;
b2.doSomething(“三个值:%s,%d,%d\n”,“一个字符串”,1,2);
返回0;
}
考虑AAAdapter更改、添加或删除参数类型的方式。基本上,我希望
B::doSomething()
简单地重定向到
B::AAdapter::doSomething()
,因此我希望这两个方法具有完全相同的签名。问题是:如何从
B
内部获取
B::AAdapter::doSomething()
的参数类型

我在上面的代码中对
B::doSomething()
的定义是我所做的最远的定义:我正在键入一个
std::tuple
,其中包含
A
中的参数类型,这样我就可以将它们解压回
B
中的参数包。不幸的是,使用上述方法,在调用
B::doSomething()
时,我仍然需要手动提供
索引…
模板参数。当然,一定有一种方法可以让这些
索引…
参数自动从元组的大小推断出来。我曾考虑过使用
std::make_integer_sequence
的方法,但这需要我为序列本身定义一个额外的方法参数(它不能是最后一个具有默认值的参数,因为在参数包之后不允许有其他参数)

有没有什么方法可以做到这一点,有没有std::tuple?需要C++17的解决方案就可以了

编辑1:

我现在意识到,我可以通过让
B
AAdapter
继承而不是让
AAdapter
对象作为成员来规避我的特定应用程序中的问题,但我仍然想知道如何解决问题而不必这样做

编辑2:

也许可以提供一些关于为什么
AAdapter
存在以及我想要实现什么的附加信息。我正在围绕一个现有的C API实现一种包装类,它实际上需要在另一个进程RPC风格中调用。因此,如果用户希望在远程进程中调用C函数,他们将在本地调用我的包装器类中的相应方法,该方法处理所有RPC内容,如类型转换、实际的远程调用和其他丑陋的细节。在上面的代码中,这个包装类由
B
表示。现在,我的包装器方法签名通常与C函数的签名不完全相同。例如,包装器可能具有
std::string\u view
而不是C函数具有的一对
const char*、size\u t
。出于此处不重要的原因,还需要有一个输出参数(指针),其中C函数有时有一个返回值


为了不必定义两个单独的方法签名(实际上是三个)并编写代码来转换每个方法的参数,我只将其中一个签名作为模板参数
RetT,ArgsT…
传递给
B
。然后,签名转换类(
AAdapter
,在上面的示例中)应用有关如何通过添加参数、更改其类型等从第一个签名自动生成第二个签名的规则
A
将保存生成的签名,
B
将保存我最初提供的签名。但是,我希望
B
提供签名为
A
invoke()
方法,从而对用户完全隐藏
A
和整个方法签名。这就是为什么我需要从
B
中访问
A
的模板参数类型,以及为什么我不能简单地删除中间类
aaadapter
这演示了如何从元组中获取具有参数类型的函数:

#include <iostream>
#include <tuple>
#include <utility>

template <
        typename ArgTuple
>
class B_Class {};

template <typename... ArgTypes>
class B_Class<std::tuple<ArgTypes...> > {
public:
        static void b(
                ArgTypes...
        ) {
                std::cout << "successful call" << std::endl;
        }
};

int main() {
        using ArgTypes = std::tuple<int, char, float, double>;
        int i; char c; float f; double d;
        B_Class<ArgTypes>::b(i, c, f, d);
}
#包括
#包括
#包括
模板<
typename参数组
>
B_类{};
模板
B班{
公众:
静态空隙b(
ArgTypes。。。
) {

std::cout这演示了如何从元组获取具有参数类型的函数:

#include <iostream>
#include <tuple>
#include <utility>

template <
        typename ArgTuple
>
class B_Class {};

template <typename... ArgTypes>
class B_Class<std::tuple<ArgTypes...> > {
public:
        static void b(
                ArgTypes...
        ) {
                std::cout << "successful call" << std::endl;
        }
};

int main() {
        using ArgTypes = std::tuple<int, char, float, double>;
        int i; char c; float f; double d;
        B_Class<ArgTypes>::b(i, c, f, d);
}
#包括
#包括
#包括
模板<
typename参数组
>
B_类{};
模板
B班{
公众:
静态空隙b(
ArgTypes。。。
) {
标准::cout

问题的核心是将元组转换为参数包

可能元组类型不是模板参数?在这种情况下,有一个简单的继承解决方案:

#包括
#包括
#包括
模板
结构BImpl{
typedef std::tuple tuple_type;
//也许你会从一些类模板中得到一个元组类型。假设结果是“tuple\u type”。
//要求:'tuple_type'=std::tuple
//要求:'tupl