从模板模板参数中提取第一个模板参数并在 class?

Extract first template parameter from a template template parameter and using it inside the class?

我有以下问题:一个class模板A有几个模板参数,我想构建一个classB,它以A为模板参数并提取A的第一个模板参数为了在某​​种方法中使用它(考虑从 std::vector 中提取 int 并返回默认的 int{})。

#include <iostream>

template<typename... Ts>
struct A {};

template<template <typename InnerType> typename U> // <--- I'd like to use InnerType!
struct B {
  InnerType foo() { return InnerType{}; }
};

int main()
{
  B<A<int>> b;
  std::cout << b.foo() << "\n"; 

  return 0;
}

我知道这种天真的方法无法编译,但我不知道如何实现这样的目标。感谢任何提示。

不能直接命名模板模板参数的模板参数。尽管它看起来你可以给它命名,但正如你注意到的那样实际上不能使用这个名字。

但是,您可以对采用单个模板参数的类型使用显式特化。

template<typename... Ts>
struct B;  // incomplete type, only needed for specialization

template<template <typename> typename U, typename InnerType>
struct B<U<InnerType>>  // specialized to be able to use InnerType
{  
  InnerType foo() { return InnerType{}; }
};

这是一个demo

对于具有多个参数的模板,您当然可以通过为这些情况添加专门化来做类似的事情。

没有InnerType。这是一个助记符。模板第一个参数预期用途的文档。它是完全可选的。 B 的声明等同于

template<template <typename> typename U> // No name
struct B {
  InnerType foo() { return InnerType{}; } // What now?
};

Class 模板不是类型。它们是生产类型的工厂。您不能向工厂查询它将使用 的 参数,因为它还不知道。此外,您定义 B 以接受模板作为参数,而实际上您打算为其提供一个类型。那是 argument/parameter 不匹配。

但是可以查询工厂的结果。如果您更改 B 的定义以接受类型而不是模板,则您可以将其专门用于从模板创建的类型。这将使工厂及其使用的参数都可推导。