Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.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/5/date/2.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++;_C++_Templates_Tuples_Std_Template Meta Programming - Fatal编程技术网

C++ 在C++;

C++ 在C++;,c++,templates,tuples,std,template-meta-programming,C++,Templates,Tuples,Std,Template Meta Programming,我想迭代元组的类型,而不是它的元素。 假设您有一个通用的基类接口Controller,并且希望有一个指针向量(为了可读性,我使用原始指针而不是智能指针):std::vector ctrls 现在,您希望将许多Controller接口的实现添加到此向量,因此可以执行以下操作: ctrls.emplace_back(new MouseCtrl()); ctrls.emplace_back(new KeyboardCtrl()); ctrls.emplace_back(new ScreenCtrl()

我想迭代元组的类型,而不是它的元素。
假设您有一个通用的基类接口
Controller
,并且希望有一个指针向量(为了可读性,我使用原始指针而不是智能指针):
std::vector ctrls

现在,您希望将许多
Controller
接口的实现添加到此向量,因此可以执行以下操作:

ctrls.emplace_back(new MouseCtrl());
ctrls.emplace_back(new KeyboardCtrl());
ctrls.emplace_back(new ScreenCtrl());
(... and so on)
但这很难看,也不完全是可扩展的(如开闭原则),因此最好有一个元组:
usingcontrollers=std::tuple
for (T : Controllers> { 
   ctrls.emplace_back(new T());
}

显然,上面的代码不是有效的C++语法。strong>所以问题是:如何做到这一点?。我已经研究了std::apply和std::visit/std::variant,但我不知道如何做(它们迭代元素,而不是类型)。

您可以使用
std::tuple\u size
std::tuple\u元素
来获取每个元组元素的类型(这将使其顺序相反,但只需稍加修改即可恢复顺序):

#包括
#包括
#包括
使用名称空间std;
使用控制器=元组;
使用ControllersContainer=vector;
模板
无效添加(ControllersContainer和ctrls)
{
ctrls.emplace_back(元组元素{});
添加(CTRL);
}
模板
无效添加(ControllersContainer和ctrls)
{
ctrls.emplace_back(元组元素{});
}
int main()
{
控制员集装箱中心;
添加(CTRL);
}

您可以使用
std::tuple\u size
std::tuple\u元素
来获取每个tuple元素的类型(这将使其按相反的顺序排列,但只需稍加修改即可恢复顺序):

#包括
#包括
#包括
使用名称空间std;
使用控制器=元组;
使用ControllersContainer=vector;
模板
无效添加(ControllersContainer和ctrls)
{
ctrls.emplace_back(元组元素{});
添加(CTRL);
}
模板
无效添加(ControllersContainer和ctrls)
{
ctrls.emplace_back(元组元素{});
}
int main()
{
控制员集装箱中心;
添加(CTRL);
}

元组中的类型只能在编译时进行迭代。
std::tuple
是一种值类型。如果您只想默认构造元素,您可以只默认构造
std::tuple
。如果您需要更复杂的初始化,那么问题就出现了,在您的情况下应该如何做,我恐怕我们无法回答我们没有进一步的信息。一般来说,你用可变模板“迭代”类型如果你不能构造元组,重复的问题就不能真正回答这个问题。这里有一个解决方案,它只适用于类型:(我不能回答一个封闭的问题)元组中的类型只能在编译时进行迭代。
std::tuple
是一种值类型。如果您只想默认构造元素,您可以默认构造
std::tuple
。如果您需要更复杂的初始化,那么问题是在您的情况下应该如何做,我恐怕我们无法回答进一步的信息。一般来说,你可以用变量模板“迭代”类型。如果你不能构造元组,重复的问题就不能真正回答问题。这里有一个解决方案,它只适用于类型:(我不能回答一个封闭的问题)重要的是要注意,这只在编译时起作用。可能不是OP想要的。问题是关于在元组中的类型上迭代。元组是一种静态类型-“迭代”只有在编译时才可能。虽然这里的迭代是用递归实现的。@StPiere这正是我要找的。你知道标准库中是否有任何东西已经提供了这种功能-这样我就可以跳过添加“add”函数,而只需通过
ctrls.emplace\u提供一些Lambda乐趣(tuple_element_t{});
?@zupazit:我不知道直接方法。另一种可能是使用逗号运算符检查make_index_序列和tuple_大小。需要注意的是,这只在编译时起作用。可能不是OP想要的。问题是在tuple中的类型上迭代。tuple是一种静态类型-“迭代”只能在编译时进行。虽然这里的迭代是用递归实现的。@StPiere这正是我要找的。你知道标准库中是否有任何东西已经提供了这种功能-这样我就可以跳过添加“添加”了吗“使用
ctrls.emplace_back(tuple_element_t{})
?@zupazit:我不知道直接方法。另一种可能是使用逗号运算符检查make_index_序列和tuple_大小。
#include <iostream>
#include <variant>
#include <vector>

using namespace std;

using Controllers = tuple<int, char, float>;
using ControllersContainer = vector<variant<int, char, float>>;

template <size_t N>
void add(ControllersContainer& ctrls)
{
    ctrls.emplace_back(tuple_element_t<N-1, Controllers>{});
    add<N - 1>(ctrls);
}

template <>
void add<0>(ControllersContainer& ctrls)
{
    ctrls.emplace_back(tuple_element_t<0, Controllers>{});
}

int main()
{
    ControllersContainer ctrls;
    add<tuple_size_v<Controllers>>(ctrls);
}