函数从模板参数中获取字段值,而不是直接访问以允许对相同信息使用不同的名称
Function to get field value from template parameter instead of direct access to allow different names for same information
我正在设计一个内部使用的库。
一个函数可以是
template<typename It>
void doStuff(It begin, It end)
{
// This is example code. The point is to show that I access the data of the iterator
doStuffInternal(it->a, it->b, it->c);
}
这个函数是一个模板,因为我想接受所有类型的迭代器,但我对迭代器产生的类型有特定的期望。
目前,我的代码假设一个对象是用类似的结构传递的
struct A
{
int a;
std::string b;
BigObject c;
};
我知道这个函数的调用代码将从外部API接收数据,数据看起来像
struct AlmostA
{
int a_;
std::string _b;
AlmostBigObject cc;
};
现在我不能将这个AlmostA
传递给我的函数,我需要将它转换为A
(或类似于A
的东西),即使所有信息都在AlmostA
中,只是名称不同(类型略有不同)。
我想做的是创建一个访问字段的函数
inline int getA(const &A a)
{
return a.a;
}
inline std::string& getB(const &A a)
{
return a.b;
}
等等,然后将我的函数重写为
template<typename It>
void doStuff(It begin, It end)
{
doStuffInternal(getA(*it), getB(*it), getC(*it));
}
然后调用代码可以定义
inline int getA(const &AlmostA a)
{
return a.a_;
}
inline std::string& getB(const &AlmostA a)
{
return a._b;
}
并使用AlmostA
的迭代器调用我的函数,而不进行任何转换。
我希望通过这种方式实现的是,调用代码可以定义它们如何提供信息,而不必强制使用具有这些特定字段的结构。
我在谷歌上搜索了一下,找不到任何代码这样做的例子。
我对C++还比较陌生,所以我想知道如果这能起作用,这种方法有什么陷阱,为什么它不受欢迎或不被使用(我知道std::swap也有类似的功能,但这是一个特殊的功能)在C++世界中,有什么可供选择的解决方案可以用不同的接口以统一的方式呈现数据?
getter函数需要在哪个命名空间中实现,以便编译器找到它们?
您的doStuffInternal(getA(*it), getB(*it), getC(*it))
对我来说似乎很可靠-对于您需要支持的每种类型,我都会使用带有显式专用化的struct
模板。
template <typename T>
struct adapter;
template <>
struct adapter<A>
{
template <typename T>
decltype(auto) a(T&& x) { return forward_like<T>(x.a); }
template <typename T>
decltype(auto) b(T&& x) { return forward_like<T>(x.b); }
// ...
};
template <>
struct adapter<AlmostA>
{
template <typename T>
decltype(auto) a(T&& x) { return forward_like<T>(x.a_); }
template <typename T>
decltype(auto) b(T&& x) { return forward_like<T>(x._b); }
// ...
};
使用decltype(auto)
作为返回类型并且forward_like
允许您保留x
的成员的值类别:
static_assert(std::is_same<decltype(adapter<A>::a(A{})), int&&>{});
A lvalue{};
static_assert(std::is_same<decltype(adapter<A>::a(lvalue)), int&>{});
const A const_lvalue{};
static_assert(std::is_same<decltype(adapter<A>::a(const_lvalue)), const int&>{});
wandbox示例(价值类别传播)
最后的代码看起来像这样:
template<typename It>
void doStuff(It begin, It end)
{
adapter<std::decay_t<decltype(*it)>> adp;
doStuffInternal(adp.a(*it), adp.b(*it), adp.c(*it));
}
在C++11中,需要使用尾部返回类型显式指定返回类型。示例:
template <typename T>
auto a(T&& x) -> decltype(forward_like<T>(x.a_))
{
return forward_like<T>(x.a_);
}
相关文章:
- 错误:未定义对"静脉类型信息::电池访问"的引用
- 如何在提升图中访问边缘信息?
- 我的单例中的数组在离开函数后没有保留信息,然后在尝试再次访问信息时崩溃
- 无法访问引用 C++ 后面的信息
- 使用TDD时隐藏文件访问实现详细信息
- 有没有办法根据用户的输入访问类对象的信息?
- 如何在C++中嵌套词法作用域可访问的作用域中声明静态信息?
- 函数从模板参数中获取字段值,而不是直接访问以允许对相同信息使用不同的名称
- 多人游戏(例如:Tibia)的作弊是如何从客户端(本例中为C++)访问信息的
- 访问类引用信息的 C++ "Incomplete type not allowed"错误(具有前向声明的循环依赖项)
- Linux C++:访问网络统计信息
- 如何在C++中访问Windows设备管理器中的信息
- 使用基对象修改/访问派生类的信息的有问题的设计
- 如何在整个程序中访问有关线程的信息
- 如何访问文件中的信息?C++
- 用于访问系统资源信息的多平台库
- 如何从作为服务运行的c++程序访问当前登录的用户信息
- 如何访问tcp标头详细信息
- 我在尝试访问矢量<string>元素时收到错误,文本中的信息
- 使类信息在运行时可访问的可扩展方式