【问题标题】:partial class template specialization with multiple arguments具有多个参数的部分类模板特化
【发布时间】:2012-09-29 00:18:39
【问题描述】:

我有一个模板类Foo,它接受两个(或更多)模板参数。我想在一个单独的类Bar 中使用它的类型。看下面的简单例子,编译没有错误:

template <typename T, typename U> class Foo { };
template <typename T, typename U> class Bar { };
int main()
{
  Bar<int, char> bar; // quick example -- int & char could be any 2 types
  return 0;
}

上面的内容有些乏味,尤其是如果Foo 需要很多模板参数并且程序员必须重新输入它们。我想要类似下面的东西,但它不能编译:

template <typename T, typename U> class Foo { };
template <typename T, typename U> class Bar; // base
template <typename T, typename U> class Bar< Foo<T, U> > { }; // specialization
int main()
{
  typedef Foo<int, char> FooType;
  Bar<FooType> bar;
  return 0;
}
test.cpp:3:60:错误:模板参数的数量错误(1,应该是 2) test.cpp:2:45:错误:为“模板类 Bar”提供 test.cpp:在函数“int main()”中: test.cpp:7:18:错误:模板参数的数量错误(1,应该是 2) test.cpp:2:45:错误:为“模板类 Bar”提供 test.cpp:7:23:错误:';' 标记之前的声明类型无效

我特别困惑,因为这种偏特化习语适用于单个模板参数;请参阅标题为:total class specialization for a template

的问题

编辑我意识到,至少就我的目的而言,我可以使用 C++11 可变参数模板来解决这个问题,如下所示。不过,我仍然想知道为什么第二个示例不起作用。

template <typename... FooTypes> class Bar;
template <typename... FooTypes> class Bar< Foo<FooTypes...> > { };

【问题讨论】:

  • 那么,有什么问题?模板类 Bar 有 1 个参数,但 Bar 应该有 2 个参数。此外,您不知道部分模板规范化的语法。阅读一些关于 C++ 的基础书籍。
  • 目前还不清楚您要在这里实现什么。我认为您需要回答基本问题:Bar 的功能是由 Foo 参数化的,还是由 T 和 U 的选择参数化的?如果是前者,您是否考虑过“template class Bar”,您可能会将 Foo 作为 F 传递?在后一种情况下,您是否只是为了方便而尝试从 Foo 中提取 T 和 U ?此页面也可能有用:cprogramming.com/tutorial/template_specialization.html

标签: c++ templates


【解决方案1】:

您的类模板Bar&lt;T, U&gt; 接受两个模板参数,但您的专业化只有一个:

template <typename T, typename U> class Bar<Foo<T, U> > {};

您的意思是让Bar 只采用一个模板参数并相应地对其进行专门化吗?

template <typename T> class Bar;
template <typename T, typename U> class Bar<Foo<T, U> > {};

请注意,特化可以依赖于不同数量的模板参数,但特化需要获得相同数量的参数。它也可以反过来工作:完整的特化可以没有模板参数:

template <> class Bar<int> {};

【讨论】:

  • 是的,这正是我想要的。谢谢!
  • +1 很好的解释,我不太确定他想要达到什么目标。这很清楚:)
【解决方案2】:

我对你在这一行中尝试做的事情有点困惑:

template <typename T, typename U> class Bar< Foo<T, U> > { }; // specialization

您是说模板需要两种类型,T 和 U,作为类型参数。 Foo 本身只是一种类型,通过使用这两个参数实例化 Foo 模板创建的类型。

我看到您希望它能够拾取并确定 T 和 U,因为您在这两个地方都使用了它们,但这并没有规避您只为两种类型的模板特化提供一个类型参数的事实。

【讨论】:

  • 很公平......我需要做什么才能让它同时接收 T 和 U 以便我可以拥有类似 Foo foo; 的东西作为酒吧的成员?
  • 您需要更改“模板 class Bar;”到“模板 class Bar;”在基线上。部分特化线保持不变。
  • 一方面,您可以让 Bar 只接受一个模板参数(如 James 所示)。然后 typedef Foo::T 和 Foo::U 以便您可以从 Bar 访问它们。当然,这意味着您从那里提供给 Bar 的所有模板参数都必须具有这两个 typedef,因此您必须考虑这是否是您想要的。查找特征以获得更详细的功能。
猜你喜欢
  • 2011-06-10
  • 2011-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-21
  • 1970-01-01
  • 2018-06-25
  • 1970-01-01
相关资源
最近更新 更多