模板化非类型模板参数的转换构造函数

Converting constructor of templated non-type template parameter

提问人:303 提问时间:11/17/2023 更新时间:11/18/2023 访问量:101

问:

当将类型扔进 时,我希望通过使用 的转换构造函数来创建。但是,出于某种原因,GCC 似乎在 .C++20 标准对非类型模板参数的此类构造或推导有何规定?T::vintt<>Nnic<int, 3>::v

#include <concepts>

template<auto...>
struct n {
    constexpr n(int x): i{x} {}
    int i;
};
template<typename T, T V>
struct c { static constexpr T v = V; };

template<n N>
using t = c<decltype(N.i), N.i>;

// clang ok, gcc nope, msvc ok
static_assert([]<typename T = t<3>>
    { return std::same_as<T, t<T::v>>; }());

现场示例


来自 GCC 的错误消息:

<source>: In instantiation of '<lambda()> [with T = c<int, 3>]':
<source>:15:41:   required from here
<source>:15:19: error: request for member 'i' in 'c<int, 3>::v', which is of
non-class type 'const int'
   15 |     { return std::same_as<T, t<T::v>>; }());
      |              ~~~~~^~~~~~~~~~~~~~~~~~~
C++ 语言-律师 C++20

评论

1赞 Artyer 11/17/2023
也许是一个更简单的例子: godbolt.org/z/hz178nroz (在“内联”类型别名时似乎是一个问题,类型没有从 -> 正确调整。我认为这是一个 GCC 错误)intn
0赞 Klaus 11/17/2023
如何推断 n 的类型?无法捕捉到模板如何攻击<自动...>应该在这里推断......
0赞 Aconcagua 11/17/2023
如果正常使用 a 或文字,则不应该在模板上下文中产生差异,所以我同意 GCC 错误@Artyer。也许写一个错误报告?constexpr intint
0赞 Aconcagua 11/17/2023
@Klaus 但是,如果这是问题所在,那么也不应该起作用。不过,解决方案应该很简单:既然是,那么模板参数集应该是空的,不是吗?t<3>auto...auto
3赞 Artyer 11/17/2023
@Klaus CTAD将其推断为空包。但是,如果您将其删除(不设为模板),问题仍然会发生n

答:

4赞 Davis Herring 11/18/2023 #1

根据评论,您的理解是正确的,这绝对是 GCC 错误。严格来说,这个问题的答案是,不幸的是,C++20 很少说明模板参数对象是如何初始化的。缺陷报告刚刚获得批准;在该链接起作用之前,以前的版本可用。