gpt4 book ai didi

c++ - 如何检查函数中的模板参数是否匹配给定类型别名的特化

转载 作者:太空狗 更新时间:2023-10-29 20:34:30 25 4
gpt4 key购买 nike

我有以下代码:

template <template <class...> class Temp, class Specialization>
struct IsSpecialization : std::false_type {};


template <template <typename...> class Temp1,
template <typename...> class Temp2, typename... Ts>
struct IsSpecialization<Temp1, Temp2<Ts...>>
: std::is_same<Temp1<Ts...>, Temp2<Ts...>> {};

struct ExprKindMerge {};
struct ExprKindSequence {};

template <class Tag, class... Args>
struct Expr {
std::tuple<Args...> tup;

constexpr std::tuple<Args...> toStdTuple() const {
return this->tup;
}

constexpr std::size_t size() const noexcept {
return std::tuple_size<decltype(tup)>{};
}
};

template <class...Args>
using MergeExpr = Expr<ExprKindMerge, Args...>;

template <class...Args>
using SequenceExpr = Expr<ExprKindSequence, Args...>;

这个函数有时会收到一个 SequenceExpr<Something>作为模板参数:

template <class FullExpr>
auto f(FullExpr expr) {
///**************THIS RETURNS FALSE I EXPECT TRUE
///Type of full expr is Expr<ExprKindSequence, ...> which is
/// the expansion of SequenceExpr<...>
if constexpr (IsSpecialization<SequenceExpr, FullExpr>::value)
//...
}

我希望能够检测到是否 FullExprSequenceExpr 的特化但由于某些未知原因它失败了。

最佳答案

失败的原因很简单。对于 SequenceExpr<ExtraArgs...>Temp2 被推断为 Expr 并且 Ts... 被推断为 ExprKindSequence, ExtraArgs... 。那么 Temp1<Ts...> 就是 Expr<ExprKindSequence, ExprKindSequence, ExtraArgs...> 显然和 Temp2<Ts...> 不一样。

我知道没有完全通用的方法来做到这一点。毕竟,这样一个假设的模板可能需要为 true 返回 IsSpecialization<std::remove_reference_t, int> ...

如果我们将其限制为在可推导上下文中使用其参数的别名模板(在您的示例中就是这种情况),那么一种可能的方法是提出问题“我可以从 Ts... 推导出 Temp<Ts...> 中的 Specialization 吗?”:

namespace detail {
template<class> class type {};
template<template<class...> class Temp, class...Ts>
void try_deduce(type<Temp<Ts...>>);
}

template <template <class...> class, class, class = void>
struct IsSpecialization : std::false_type {};

template <template <typename...> class Temp, class Specialization>
struct IsSpecialization<Temp, Specialization,
decltype(detail::try_deduce<Temp>(detail::type<Specialization>()))>
: std::true_type {};

static_assert(IsSpecialization<SequenceExpr, SequenceExpr<int>>()());
static_assert(IsSpecialization<Expr, SequenceExpr<int>>()());
static_assert(!IsSpecialization<MergeExpr, SequenceExpr<int>>()());
static_assert(!IsSpecialization<SequenceExpr, MergeExpr<int>>()());

关于c++ - 如何检查函数中的模板参数是否匹配给定类型别名的特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48177409/

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