【发布时间】:2018-02-10 18:09:00
【问题描述】:
考虑以下程序:
#include <tuple>
#include <vector>
#include <iostream>
#include <type_traits>
template <class T>
struct ordered {};
template <class... T>
struct ordered<std::tuple<T...>>
{
using type = /* a reordered tuple */;
};
template <class T>
using ordered_t = typename ordered<T>::type;
int main(int argc, char* argv[])
{
using type1 = std::tuple<char, std::vector<int>, double>;
using type2 = std::tuple<std::vector<int>, double, char>;
std::cout << std::is_same_v<type1, type2> << "\n"; // 0
std::cout << std::is_same_v<ordered_t<type1>, ordered_t<type2>> << "\n"; // 1
return 0;
}
ordered 帮助器必须对元组中的类型重新排序,以便具有相同类型但排序不同的两个元组导致相同的元组类型:可以是第一个,第二个,甚至是另一个:它只需要具有相同的大小和相同的元素,但具有唯一的顺序(无论此顺序如何)。
是否可以在编译时使用模板元编程技术做到这一点?
【问题讨论】:
-
有可能吗?是的。无论你得到什么答案,Andrei Alexandrescu 早在 2001 年就曾写过关于在“现代 C++ 设计”中做这些事情的文章。细节无疑会有所不同,但核心思想是相同的。
-
@StoryTeller:如果
T != T2但sizeof(T1) == sizeof(T2)会怎样?您将如何唯一地对它们进行排序,以便std::is_same按预期工作? -
@Nawaz - 对任何其他类型的数据执行相同的操作。如果库不能,则强制用户提供任意顺序。这并非不可能。可以像添加一个或两个模板专业化一样简单。
-
@StoryTeller:这将算法变成了一个怪物,因为很难为每个大小相等的这样的对提供模板专业化等。那么为什么问题会是,为什么要使用这种排序 metafn 开始呢?为什么不手动执行此操作?似乎这方面缺乏 C++。应该有一种方法可以在编译时对类型进行排序.. 一个编译时运算符,相当于
std::less<>用于类型等。 -
@Vincent:这整个问题有可能是 XY 问题吗?如果您只需要比较两个元组的等效性,那么可能不需要对它们进行排序 - 使用类型别名技术进行搜索,即使 n^2 可能比对两个集合进行排序并比较它们更快(好吧,我不会赌一把,但值得一试)。
标签: c++ types tuples template-meta-programming c++17