gpt4 book ai didi

c++ - 在模板模板参数的情况下,非类型模板参数的占位符类型是否可互换

转载 作者:IT老高 更新时间:2023-10-28 22:05:26 35 4
gpt4 key购买 nike

考虑一个简单的例子:

int x;

template <template <auto> class TT>
struct Foo {
void foo() {
TT<(x)> tt;
static_cast<void>(tt);
}
};

template <decltype(auto)>
struct Bar { };


int main() {
Foo<Bar> foobar;
foobar.foo();
}

[clang]似乎处理 decltype(auto) 占位符的想法,尽管在模板模板参数声明中使用 auto 没有问题。

[gcc]另一方面 - 不太好:

prog.cc:6:13: error: the value of 'x' is not usable in a constant expression


像往常一样 - 根据标准,哪些行为是预期的?或者也许一切皆有可能并且代码格式不正确(这次我想不是但不能明确排除)?

PS。很抱歉再次破坏了其中一个编译器;)

最佳答案

这里的原始答案是 Foo<Bar>格式错误,我现在实际上认为它格式正确。但最终还是基于 clang 的 bug。


我什至认为 Foo<Bar>格式不正确。 遵循 P0522 的新规则那是:

A template-argument matches a template template-parameter P when P is at least as specialized as the template-argument A

地点:

A template template-parameter P is at least as specialized as a template template-argument A if, given the following rewrite to two function templates, the function template corresponding to P is at least as specialized as the function template corresponding to A according to the partial ordering rules for function templates ([temp.func.order]). Given an invented class template X with the template parameter list of A (including default arguments):

  • Each of the two function templates has the same template parameters, respectively, as P or A.
  • Each function template has a single function parameter whose type is a specialization of X with template arguments corresponding to the template parameters from the respective function template where, for each template parameter PP in the template parameter list of the function template, a corresponding template argument AA is formed. If PP declares a parameter pack, then AA is the pack expansion PP... ([temp.variadic]); otherwise, AA is the id-expression PP.

If the rewrite produces an invalid type, then P is not at least as specialized as A.

这意味着要验证 Foo<Bar>本身没问题,我们合成:

template <decltype(auto) I> struct X;

template <auto I> void __f(X<I> ); // P
template <decltype(auto) I> void __f(X<I> ); // A

这里的所有类型都是有效的(所以最后一条语句不适用)。现在,通常当我们进行部分排序时,它是在重载决议或选择类模板特化的上下文中,在这种情况下,我们正在寻找的是 "more specialized"函数模板,其中Fmore specialized than G如果 F至少与 G 一样专业和 G至少不像 F 那样专业.

但在这种情况下,我们并不关心哪个更专业。我们只需要P至少与 A 一样专业.这一切都意味着从 A 中扣除必须成功。至P .所以如果我们合成一些独特的类型U有一些值(value)V , 我们可以推导出 X<I>来自 X<V> ?是的。因此,P至少与 A 一样专业, 所以模板参数 Bar匹配模板参数TT .


现在,过了这一点,我会说这是一个铿锵的错误。模板模板参数template <auto> ,这是我们应该用来验证表达式的。使用非类型模板参数 auto , 我们会尝试使用 x作为一个值 - 但是 x不是一个有效的常量表达式,所以这应该失败。 clang 似乎在使用 template <decltype(auto) >直接 - 我不确定这是否有效。

也就是说,我不确定这个案例是否已被考虑 - 我看不出有任何措辞,因此值得提出一个问题。

关于c++ - 在模板模板参数的情况下,非类型模板参数的占位符类型是否可互换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46309228/

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