gpt4 book ai didi

c++ - GCC/CLang 不同意模板模板参数的部分特化

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

GCC 和 clang 不同意此代码。

#include <type_traits>

template <typename T, template <typename...> typename Tpl>
struct storage {
using type_t = T;

template <typename... Args>
using storage_tpl = Tpl<Args...>;
};

template <typename T, template <typename...> typename>
struct F{
constexpr static int x = 1;
};

template <typename T >
struct F<T, std::void_t>{
constexpr static int x = 2;
};

int f() {
using S = storage<int, std::void_t>;

static_assert(F<int, S::storage_tpl>().x == 2);

return F<int, S::storage_tpl>().x;
}

根据 clang S::storage_tpl 不是 std::void_t;结果它选择了主模板 F 而不是部分特化,因此选择了断言。

乍一看,GCC 似乎是对的,因为它知道嵌套模板只是 std::void_t 的别名,但也许它太聪明了,标准要求 S::storage_tplstd::void_t 必须是两个不同的模板。

谁是对的?

最佳答案

目前看来这是未指定的,h/t to T.C.看起来这被 CWG defect report 1286 涵盖了其中说:

Issue 1244 was resolved by changing the example in 17.5 [temp.type] paragraph 1 from

 template<template<class> class TT> struct X { };
template<class> struct Y { };
template<class T> using Z = Y<T>;
X<Y> y;
X<Z> z;

to

  template<class T> struct X { };
template<class> struct Y { };
template<class T> using Z = Y<T>;
X<Y<int> > y;
X<Z<int> > z;

In fact, the original intent was that the example should have been correct as written; however, the normative wording to make it so was missing. The current wording of 17.6.7 [temp.alias] deals only with the equivalence of a specialization of an alias template with the type-id after substitution. Wording needs to be added specifying under what circumstances an alias template itself is equivalent to a class template.

并提出以下决议:

Add the following as a new paragraph following 17.6.7 [temp.alias] paragraph 2:

When the type-id in the declaration of alias template (call it A) consists of a simple-template-id in which the template-argument-list consists of a list of identifiers naming each template-parameter of A exactly once in the same order in which they appear in A's template-parameter-list, the alias template is equivalent to the template named in the simple-template-id (call it T) if A and T have the same number of template-parameters. [Footnote: This rule is transitive: if an alias template A is equivalent to another alias template B that is equivalent to a class template C, then A is also equivalent to C, and A and B are also equivalent to each other. —end footnote] [Example:

  template<typename T, U = T> struct A;

template<typename V, typename W>
using B = A<V, W>; // equivalent to A

template<typename V, typename W>
using C = A<V>; // not equivalent to A:
// not all parameters used

template<typename V>
using D = A<V>; // not equivalent to A:
// different number of parameters

template<typename V, typename W>
using E = A<W, V>; // not equivalent to A:
// template-arguments in wrong order

template<typename V, typename W = int>
using F = A<V, W>; // equivalent to A:
// default arguments not considered

template<typename V, typename W>
using G = A<V, W>; // equivalent to A and B

template<typename V, typename W>
using H = E<V, W>; // equivalent to E

template<typename V, typename W>
using I = A<V, typename W::type>; // not equivalent to A:
// argument not identifier

—end example]

但此解决方案存在问题,缺陷报告仍然有效。

关于c++ - GCC/CLang 不同意模板模板参数的部分特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52725022/

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