gpt4 book ai didi

c++ - 在 C++2a 中,可以将类型用占位符指定为推导类类型的非类型模板参数传递给另一个模板吗?

转载 作者:搜寻专家 更新时间:2023-10-31 00:50:28 26 4
gpt4 key购买 nike

template<auto>
struct S {};

template<S>
struct T {};

using T0 = T<S<0>{}>; // compiles

template<S s>
using T1 = T<s>; // fails

T0 使用 GCC 9.1 编译但 T1 不:

error: class template argument deduction failed
error: no matching function for call to 'S(S<...auto...>)'

这是 C++2a 中的预期行为吗?

编辑:编译失败似乎在推导类型时发生,而不是在使用推导类类型的占位符时发生:

template<auto s>
using T1 = T<s>; // also fails

最佳答案

T0应该是错误的,因为 S<0>不具有强结构平等。

T1应该是错误的,不需要诊断,因为目前没有 T1 的特化那将是有效的(因为 S 没有具有强结构相等性的特化)。


这是因为对类类型作为非类型模板参数的要求来自 [temp.param]/4 :

A non-type template-parameter shall have one of the following (optionally cv-qualified) types:

  • a literal type that has strong structural equality ([class.compare.default]),
  • an lvalue reference type,
  • a type that contains a placeholder type ([dcl.spec.auto]), or
  • a placeholder for a deduced class type ([dcl.type.class.deduct]).
template<S>
struct T {};

属于最后一种情况。但是当我们尝试 T<S<0>{}> , 我们推导出占位符 S作为S<0>从 CTAD,我们点击了 [temp.arg.nontype]/1 :

If a deduced parameter type is not permitted for a template-parameter declaration ([temp.param]), the program is ill-formed.

这让我们回到最初的引用,现在我们需要一种叫做“强结构平等”的东西。这在 [class.compare.default]/4 中定义作为:

A type C has strong structural equality if, given a glvalue x of type const C, either:

  • C is a non-class type and x <=> x is a valid expression of type std::strong_­ordering or std::strong_­equality, or

  • C is a class type where all of the following hold:

    • All of C's base class subobjects and non-static data members have strong structural equality.
    • C has no mutable or volatile non-static data members.
    • At the end of the definition of C, overload resolution performed for the expression x == x succeeds and finds either a friend or public member == operator that is defined as defaulted in the definition of C.

在我们的例子中,我们是一个类类型,但是虽然我们所有的子对象都具有很强的结构相等性(很简单,因为我们没有子对象),我们没有有适当的 operator== .要解决这个问题:

template <auto>
struct S {
friend bool operator==(S const&, S const&) = default;
};

现在一切应该编译(但不是因为 gcc 还没有完全支持它,实际上甚至不允许你声明所需的默认 operator==)。

关于c++ - 在 C++2a 中,可以将类型用占位符指定为推导类类型的非类型模板参数传递给另一个模板吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57383146/

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