将成员元组传递到非成员结构,而不在模板中指定它
passing member tuple to non-member struct without specifying it in template
为了避免XY问题,我有一个带有异构容器的类,基本上std::tuple
。我想让类能够接受访问者,将它们应用于元组的每个元素(不确定我是否静态应用它)。访客的访问功能将被模板化,因此他们将能够充分利用某些类型的专业化。
问题:
当我想应用访客时,我需要遍历一个容器,以获取有关访客、元组和即将访问的元素索引的信息。但是当我想创建成员函数时,我发现我无法部分地专门化它。这是我提出的解决方案,但我想以某种方式传递元组而不在模板参数中指定包含元组的类型。
#pragma once
#include <tuple>
#include <functional>
template <typename Visitor, int N, typename ... DataTypes>
struct Extractor
{
static void applyVisitor(Visitor& v, std::tuple<DataTypes...>& t)
{
Extractor<Visitor, N - 1, DataTypes...>::applyVisitor(v, t);
v.visit(std::get<N>(t));
}
};
template <typename Visitor, typename ... DataTypes>
struct Extractor <Visitor, 0, DataTypes...>
{
static void applyVisitor(Visitor& v, std::tuple<DataTypes...>& t)
{
v.visit(std::get<0>(t));
}
};
template <typename ... DataTypes>
class MyTuple
{
std::tuple<DataTypes...> data;
public:
MyTuple(std::tuple<DataTypes...> data_) : data(data_) {}
template <typename Visitor>
void acceptVisitor(Visitor& v)
{
Extractor<Visitor, sizeof...(DataTypes) - 1, DataTypes...>::applyVisitor(v, data);
}
};
我正在考虑 OOD,因此对类数据进行操作的每个函数都应该最好是成员函数,但似乎C++模板来自另一个世界。如果我做得不对,请提出另一种解决方案。
编辑:
正如评论中问的那样,这是访客和客户呼叫acceptVisitor()
的示例
游客
#pragma once
#include <iosfwd>
class Visitor
{
std::ostream& os;
public:
Visitor(std::ostream& outputStream) :os(outputStream) {}
template <typename T>
void visit(T& data)
{
std::cout << data << "n";
}
};
主要
#include "HeteContainer.h"
#include "Visitor.h"
#include <iostream>
#include <string>
#include <cstdlib>
int main()
{
Visitor v(std::cout);
MyTuple<int, int, std::string> m({ 1, 1, "abc" });
m.acceptVisitor(v);
std::system("pause");
}
您可以避免递归并改用std::index_sequence
:
template <typename Visitor, typename... DataTypes, std::size_t... Idx>
void applyVisitor(Visitor& v, std::tuple<DataTypes...>& t, std::index_sequence<Idx...>)
{
using expander=int[];
(void)expander{ (v.visit(std::get<Idx>(t)), 0)... };
}
然后你的acceptVisitor
函数变成这样:
template <typename Visitor>
void acceptVisitor(Visitor& v)
{
applyVisitor(v, data, std::index_sequence_for<DataTypes...>{});
}
现场演示
相关文章:
- 您自己的类型的结构化绑定,不是结构或元组(通过公共成员函数)
- std::元组作为成员替换,方便宏
- 具有多个空成员的 std::元组上的比较无法在 GCC 上编译
- 将元组成员包装在其他模板化类型中
- 标准::元组成员逐个成员比较失败
- 以先前的通话递归致电每个元组成员
- 确定模板中结构或元组的成员偏移
- 如何创建一个 std::tuple,其中包含由索引元组指定的向量中的成员
- 如何检查两个元组的所有成员是否不同
- 初始化类成员初始值设定项列表中的向量元组
- 通过模板成员函数访问私有元组元素
- 对元组的每个元素进行泛型调用成员函数
- 静态元组类成员的 constexpr 存在链接器错误
- 在可变参数模板类的构造函数中初始化元组成员
- 将成员元组传递到非成员结构,而不在模板中指定它
- 成员初始值设定项列表:从返回元组的函数初始化两个成员
- 带成员函数指针的元组
- 重载成员函数访问元组和递归累加结果失败的原因
- 在可变模板函数中创建成员函数指针元组
- void成员函数的元组