问题很简单:查看代码。两个静态断言都通过了。我不希望第二个通过。这是一个错误还是正常行为?
#include <array>
#include <type_traits>
template <template <class...> class Temp, class Specialization>
struct IsSpecialization : std::false_type {};
template <template <class...> class Temp, class... Ts>
struct IsSpecialization<Temp, Temp<Ts...>> : std::true_type {};
template <class...Args>
struct A {};
template <class...Args>
using AT = A<Args...>;
int main() {
static_assert(IsSpecialization<A, A<int>>{});
static_assert(!IsSpecialization<AT, AT<int>>{});
}
答案 0 :(得分:6)
_posts
会被推断两次:
Temp
与Temp
相匹配。这通常会将AT
推断为Temp
。AT
与Temp<Ts...>
相匹配。这会将AT<int>
推断为Temp
,因为A
等同于AT<int>
,此推论将永远不会推断别名模板(请参阅[temp.alias]/2)。整体扣除成功 - 部分专精化是匹配 - 如果两次扣除给A<int>
相同的值,即iff Temp
和AT
被认为是等效的。他们是is currently an open question。
答案 1 :(得分:2)
不是解释(请参阅T.C.的答案),但解决方法是:修改IsSpecialization
的真实版本,如下所示
template <template <typename...> class Temp1,
template <typename...> class Temp2, typename... Ts>
struct IsSpecialization<Temp1, Temp2<Ts...>>
: public std::is_same<Temp1<Ts...>, Temp2<Ts...>>
{ };
T.C。请注意,使用原始代码时,AT
在被视为容器时被推断为AT
,而A<Ts...>
被视为类型。
诀窍是在不同的模板模板参数中推导AT
和A
,应用相同的模板类型(Ts...
)获取AT<Ts...>
和A<Ts...>
。但AT<Ts...>
和A<Ts...>
属于同一类型且std::is_same
了解它。