【问题标题】:Automatic template deduction C++20 with aggregate type聚合类型的自动模板推导 C++20
【发布时间】:2022-01-12 13:51:17
【问题描述】:

我对这段 C++ 代码感到困惑:

template <class T>
struct Foo {
  T value;
};
 
int main() {
    return Foo<int>(0).value;
    // Below code works as well in gcc
    // return Foo(0).value;
}

它可以使用 C++20 标准(但不是 C++17 标准)和最新的 MSVC 中的 GCC 10 编译,但不能使用 clang 13 或 14,即使在 C++20 中也是如此。

根据标准(来自cppreference),至少在指定模板类型时应该可以实例化Foo

为什么这与 C++20 相关?我看不出模板推导规范有什么变化(我可能遗漏了一些东西)。

另外(这很奇怪),当我们调用 Foo 而不指定模板类型 (Foo(0)) 时,C++20 模式下的 GCC 甚至可以编译。

神螺栓链接 here

【问题讨论】:

  • 这看起来不像聚合初始化(您在链接中引用的内容),而更像是对象构造函数调用。
  • @roccobaroccoSC C++20 允许使用括号构造聚合。

标签: c++ templates c++20 aggregate-type


【解决方案1】:

它在 C++20 标准中使用 GCC 10 编译(但不是在 C++17 标准中) 和最新的 MSVC。

这是因为 GCC 10 和最新的 MSVC 实现了allow initializing aggregates from a parenthesized list of values,这允许我们使用括号来初始化聚合。

另外(这很奇怪),C++20 模式下的 GCC 在我们调用时甚至可以编译 Foo 未指定模板类型 (Foo(0))。

这是因为 GCC 10 实现了class template argument deduction for aggregates,这使得T 自动推导出为int


请注意,clang 目前没有实现这两个 C++20 特性,所以你的代码不能被 clang 接受。

您可以参考cppreference获取当前编译器对C++20特性的支持。

【讨论】:

【解决方案2】:

关于你的链接,编译器会告诉你你的调用有什么问题:

错误:没有匹配的函数调用 'Foo::Foo(int)'

所以,问题在于您尝试调用一个不存在的构造函数。您的类 Foo 仅具有默认构造函数 Foo()

只需将return Foo&lt;int&gt;(0).value; 更改为return Foo&lt;int&gt;().value; 即可。否则,您将需要像 Foo(T) {} 这样的构造函数。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2020-07-09
  • 1970-01-01
  • 1970-01-01
  • 2019-11-29
  • 2022-01-11
  • 1970-01-01
  • 1970-01-01
  • 2011-10-07
相关资源
最近更新 更多