gpt4 book ai didi

可变类型列表前缀的 c++ std::tuple

转载 作者:可可西里 更新时间:2023-11-01 16:18:34 25 4
gpt4 key购买 nike

我试图从一些可变类型列表中提取类型前缀。这是我的尝试:

#include <tuple>
#include <type_traits>

template <typename... Ts>
struct pack{};

template <size_t n, typename... Args>
struct prefix_tuple;

template <size_t n, typename... TPrefix, typename Tnext, typename... Ts>
struct prefix_tuple<n, pack<TPrefix...>, Tnext, Ts...>{
using type = typename
prefix_tuple<n-1, pack<TPrefix..., Tnext>, Ts...>::type;
};

template <typename... TPrefix, typename... Ts>
struct prefix_tuple<0, pack<TPrefix...>, Ts...>{
using type = std::tuple<TPrefix...>;
};

template <size_t n, typename... Args>
using prefix_tuple_t = typename
prefix_tuple<n, pack<>, Args...>::type;

bool f(){
return std::is_same_v<prefix_tuple_t<2, int, char, double>,
std::tuple<int, char> >;
}

这在 gcc 8.2 上失败了:

error: ambiguous template instantiation for 'struct prefix_tuple<0, pack< int, char>, double>'

第二个专业似乎比第一个更具体,所以我不明白为什么这里有歧义。我做错了什么?

附言这在 clang 7.0 上也失败并出现类似错误,但似乎适用于 icc 19.0.1 和 msvc 19.16。

最佳答案

经过更多的研究,这里是我的发现:

这些是 Partial Ordering规则:

1) If only one specialization matches the template arguments, that specialization is used.
2) If more than one specialization matches, partial order rules are used to determine which specialization is more specialized. The most specialized specialization is used, if it is unique (if it is not unique, the program cannot be compiled).
3) If no specializations match, the primary template is used

和:

Informally "A is more specialized than B" means "A accepts a subset of the types that B accepts".

AB 分别成为我的代码中的第一个和第二个特化。A 接受数字 n 大于 0 的结构(B 不接受)。另一方面,B 接受前缀包后带有 0 类型的结构(A 不接受)。因此 AB 都不是“最专业的”,程序不应该编译。也就是icc和msvc是错误的。


可能的解决方案:

假设我添加了评论中提到的以下第三个特化(称之为C):

template <typename... TPrefix, typename Tnext, typename... Ts>
struct prefix_tuple<0, pack<TPrefix...>, Tnext, Ts...>{
using type = std::tuple<TPrefix...>;
};

C 既不接受大于 0 的数字 n,也不接受前缀包后面有 0 类型的结构。因此它是最专业的。此外,如果 n==0C 不能使用,A 也不能,所以这解决了 A 之间的歧义B

添加此代码后,该代码可与 gcc、clang 和 msvc 一起使用,但 icc 拒绝它并出现以下错误:

error: more than one partial specialization matches the template argument
list of class "prefix_tuple<0UL, pack < int, char >, double>":
"prefix_tuple<0UL, pack < TPrefix... >, Tnext, Ts...>"
"prefix_tuple<0UL, pack < TPrefix... >, Ts...>"

正如我之前提到的,第一个 (C) 比第二个 (B) 更专业,所以我必须推断 icc 又是错误的。

关于可变类型列表前缀的 c++ std::tuple,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55207831/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com