c++ - 非类型模板参数中的C++类类型:推导指南失败

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

问题

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

我尝试使用一个类的模板参数(在下面的示例中为struct C),以便推断第二个类的相应类模板参数(在下面的示例中为struct B)。我在此利用针对该特定目的编写的自定义类模板参数推导指南。

在这个最小的示例中,我要提取的信息是两个int
如果我将这些原始类型用作模板参数,则一切正常。但是,当我将信息合并为一个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<af>...无法在构造函数中扩展的问题?

    最佳答案

    @AndiG和@walnut用他们对我的原始问题的评论来回答我的问题。

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

    关于c++ - 非类型模板参数中的C++类类型:推导指南失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59882343/

    相关文章:

    c++ - 我应该使用以下哪个实现来进行标签分派(dispatch)?为什么?

    c++ - static_assert 未在模板参数中评估

    c++ - std::future::then()和并发TS在哪里?

    c++ - "requires"忽略一个字段不是静态的

    c++ - 使用 Visual Studio C++ 20 导入公共(public)模块文件夹的最佳方法

    c++ - 为什么变量不是 C++ 中的左值?

    c++ - 如何在 Windows 的 C++ 中以 char * 格式获取当前窗口的标题?

    symfony - 如何将 Twig 表达式作为参数传递给模板,然后使用模板的上下文执行它?

    c++ - 将具有默认参数的 lambda 函数复制到变量

    C++ move 语义(和右值引用)与普通引用