【问题标题】:C++ Class types in non-type template parameters: deduction guide fails非类型模板参数中的 C++ 类类型:演绎指南失败
【发布时间】:2020-05-09 22:45:57
【问题描述】:

问题

我正在使用 c++2a 功能,该功能允许 structs / std::array 作为模板参数(g++-9.2.0clang 尚不支持)。 该功能称为Class types in non-type template parameters,并在P0732R2 中提出。

我尝试使用一个类的模板参数(以下示例中的结构C)来推断第二类的相应类模板参数(以下示例中的结构B)。我特此使用我为此特定目的编写的自定义类模板参数推导指南。

在这个最小示例中,我要提取的信息是两个ints。 如果我使用这些原始类型作为模板参数,一切正常。但是,当我将信息合并到一个std::pair 或自定义std::struct 中时,扣费失败。

代码

分离信息

下面的代码运行良好。

#include <array>

/// Data structure which contains a constexpr context to be used for type deduction later
template <int aa, int ab> struct C {};

/// Class which has to find out its own type
template <std::size_t count, std::array<int, count> a, std::array<int, count> b> struct B {
  template <int... aa, int... bb> explicit B(C<aa, bb> ... c) {}
};

/// Class deduction guide
template <int... aa, int... ab> B(C<aa, ab>... c)
    ->B<sizeof...(aa) + 1, std::array<int, sizeof...(aa) + 1>{aa...},
        std::array<int, sizeof...(aa) + 1>{ab...}>;

int main() { B k{C<1, 2>{}, C<2, 3>{}}; }

综合信息

下面的代码编译失败。

#include <array>

/// Change: A contains the information from the previous example in a structs.
struct A { int a; int b; };

/// Data structure which contains a constexpr context to be used for type deduction later
template <A a> struct C {};

/// Class which has to find out its own type
template <std::size_t count, std::array<A, count> a> struct B {
  template <A... af> explicit B(C<af> ... c) {}
};

/// Class deduction guide
template <A... af> B(C<af>... c)->B<sizeof...(af) + 1, std::array<A, sizeof...(af) + 1>{af...}>;

int main() { B k{C<A{1, 2}>{}, C<A{2, 3}>{}}; }

错误输出:


main.cc: In function ‘int main()’:
main.cc:24:14: error: class template argument deduction failed:
   24 |   B k {c1, c2};
      |              ^
main.cc:24:14: error: no matching function for call to ‘B(C<A{1, 2}>&, C<A{1, 2}>&)’
main.cc:17:20: note: candidate: ‘B(C<((const A)af)>...)-> B<(sizeof... (af) + 1), std::array<A, (sizeof... (af) + 1)>{(const A)af ...}> [with A ...af = {}]’
   17 | template <A... af> B(C<af>... c)->B<sizeof...(af) + 1, std::array<A, sizeof...(af) + 1>{af...}>;
      |                    ^
main.cc:17:20: note:   candidate expects 0 arguments, 2 provided
main.cc:14:31: note: candidate: ‘template<long unsigned int count, std::array<A, count> a, A ...af> B(C<((const A)af)>...)-> B<count, a>’
   14 |   template <A... af> explicit B(C<af> ... c) {}
      |                               ^
main.cc:14:31: note:   template argument deduction/substitution failed:
main.cc:24:14: note:   couldn’t deduce template parameter ‘count’
   24 |   B k {c1, c2};

我现在想知道是什么导致了这个问题。发生错误是因为

  • ...我想要达到的目标一般是不可能的
  • ...g++ 中还没有实现一些东西
  • ...我的推理指南搞砸了?

我也不明白错误信息。该函数似乎期望零参数。是C&lt;af&gt;...不能在构造函数中展开的问题吗?

【问题讨论】:

  • 你用-std=c++2a编译吗? it works 给我
  • @AndyG 但它不适用于 GCC 9.2.0,只能用于头部。 OP:这似乎是一个很好的指标,表明它只是以前版本中的一个错误。
  • 是的,我使用g++ -std=c++2a -fno-strict-aliasing -fwrapv -save-temps main.cc 进行编译,但g++ -std=c++2a main.cc 也不适用于我。但我会检查它是否适用于 g++-10。
  • 非常感谢,我还没有尝试过,你是对的,使用更新版本的 g++ 它可以工作:) 我是 StackOverflow 的新手;我可以以某种方式接受您的答案/投票吗,因为切换到更新版本的 g++ 对我有用并解决了问题。不过,我还有一个问题:如果你是我,你会向 GNU 错误跟踪器报告这个问题吗?由于此问题似乎在最新版本中有效,因此似乎已修复
  • 如果该错误已在较新版本中修复,我认为您不应该将其报告给错误跟踪器。如果有人决定从这些 cmets 写出实际答案,您可以接受(并在您有足够的声誉后投票)。你也可以自己写答案。

标签: c++ templates c++20 template-argument-deduction


【解决方案1】:

@AndiG 和 @walnut 用他们的 cmets 回答了我的问题。

我的问题可能是由我的 G++-9 版本中的错误引起的。我目前没有使用最新版本的g++-9,这个bug至少在g++-10中解决了。在我编译的g++-10.0 版本中(3684bbb022c)我不再收到错误消息。

【讨论】:

    猜你喜欢
    • 2019-09-23
    • 2021-06-20
    • 1970-01-01
    • 1970-01-01
    • 2022-12-22
    • 2011-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多