我想找到一个类型为T的元组元素的索引。我想在编译时完成这个任务。怎么做呢?每个类型只在元组中使用一次,所以类型是唯一的。
以下是我目前掌握的信息:
using Tuple_Type = std::tuple
<
CoolType,
SomethingElse,
Boing,
BingBang
>;
Tuple_Type m_pool_of_data;
template <typename T>
inline T& Get()
{
return std::get<T>(m_pool_of_data); // This one works great
}
template <typename T>
inline int GetIndexOfType()
{
return ??????; // How to make this work?
}
Boing b = Get<Boing>(); // Gets the element of type Boing from the tuple
int index_of_type = GetIndexOfType<Boing>(); // Should return 2
字符串
如何使用int GetIndexOfType()?
我用的是C++17
额外信息:
std::get正确区分由
using Boing = int;
using BingBang = int;
型
但是std::is_same_v似乎认为这两个是相同的类型。所以如果我想使用std::is_same_v解决这个问题,这是一个问题。
解决方案:
这是我想出来的,基于这个线程中给出的想法和反馈。似乎按预期工作。
template <typename T, int I>
static constexpr int GetTypeIndexFromTuple()
{
constexpr int tuple_element_count = std::tuple_size<Tuple_Type>();
// No data type found?
if constexpr (I >= tuple_element_count)
{
return -1;
} else {
// Data type found?
if constexpr (std::is_same_v<std::tuple_element_t<I, Tuple_Type>, T>)
return I;
else
return GetTypeIndexFromTuple<T, I + 1>(); // Test the next tuple element
}
}
template <typename T>
inline int GetTypeIndex()
{
int index = GetTypeIndexFromTuple<T, 0>();
assert(index != -1);
return index;
}
型
这似乎工作。
我还把所有的数据类型都 Package 在一个结构体中,如果它们最初不是结构体或类的话。这解决了相同数据类型的冲突。
这个系统在一个类中使用,因为我正在开发的类是一个专用容器。
2条答案
按热度按时间7vhp5slm1#
使用C++20模板化lambda的答案:
字符串
fold表达式是一种令人费解的方式,表示“当类型不相同时,递增索引”。
尽管更规范的方法是使用注解中建议的
std::index_sequence
。演示:https://godbolt.org/z/5a4P5Phfa
通过编写自己的
type_identity
并将lambda转换为自由函数,它可以轻松地适应C++17。型
演示:https://godbolt.org/z/Yhrrxv5dq
nnvyjq4y2#
首先,注意
GetIndexOfType
真的不应该是一个函数,因为你没有使用任何对象,你只是在使用类型进行元编程。在这种情况下,类模板通常更优雅:测试
型
进一步说明
但是
std::is_same_v
似乎认为这两个是相同的类型。所以如果我想用std::is_same_v
解决这个问题,这是一个问题。这不是你能解决的;这是C++的一个基本问题。别名是弱的,即
typedef
和using
不会创建一个不同的类型。std::is_same_v<int, alias_for_int>
总是为真,无论你做什么。另请参阅Strongly typed using and typedef了解变通方法。