【问题标题】:template template function definition模板模板函数定义
【发布时间】:2018-06-27 02:05:57
【问题描述】:

我有一个名为 Array 的模板类

template<typename T, int dimension>
class Array<typename T, int dimension>{

    //definition of the class

}

我想编写一个非成员函数转换,以便我可以将 Array 转换为不同的类型。例如

Array<int, 2> a;
Array<float, 2> b = cast<float>(a);

我应该如何编写这个函数?我对如何声明它而不是如何实现详细的转换更感兴趣。我试过了

template<template<typename T, int dimension> class Array, typename New_T, int dimension>
Array<typename New_T, int dimension> cast(Array<typename T, int dimension> a){

// detailed implementation of casting, which I do not care for this question.

}

但无法通过编译。

【问题讨论】:

  • 在没有亲自测试过的情况下,我不确定您是否真的需要一个模板模板。我认为函数可以是:template&lt;typename T, int dimension, typename New_T&gt; Array&lt;New_T, dimension&gt; cast(Array&lt;T, dimension&gt;)

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


【解决方案1】:

这里根本不需要模板模板参数。简单的typename 和int 参数就可以了:

template <typename T, int dimension>
class Array
{
    // ...
};

template <typename NewT, typename T, int dimension>
Array<NewT, dimension> cast(const Array<T, dimension>& a)
{
    // ...
}

Live Demo

当您想要接受不同类型的模板时,您只需要模板模板参数。例如,如果您希望 cast 能够接受 Array 或 std::array,则可以使用模板模板参数:

template<typename NewT, typename T, auto dimension, template<typename, auto> typename ArrayT>
ArrayT<NewT, dimension> cast(const ArrayT<T, dimension>& a)
{
    // ...
}

Live Demo

请注意,在这种情况下,我还将dimension 的类型更改为auto,因为std::array 使用size_t 作为其维度,而您的Array 使用int。

【讨论】:

  • 很好的解释!我一开始尝试使用模板方法,但失败了。我发现原因,正如@max66所说,是因为我没有将NewT类型放在模板的第一个位置。
【解决方案2】:

我应该如何编写这个函数?我更感兴趣的是如何定义它而不是如何实现详细的转换。

我猜是这样的

template <typename ToT, typename FromT, int Dim>
Array<ToT, Dim> cast (Array<FromT, Dim> const & inA)
 {
   // ...
 }

将ToT(to-type)放在首位很有用,因此您可以明确它并让FromT 和Dim 从inA 值推导出来。

--- 编辑---

OP 询问

知道为什么我必须把它 [ToT] 放在第一位吗?

您不必将ToT 放在首位。但这可以简化您的生活。

重点是FromT 和Dim 可以从inA 参数中推导出来; ToT 不能从参数推导出来,所以你必须明确它。

但是如果你想显式一个模板参数,你必须显式前面的参数。所以如果你把ToT放在最后,你必须调用cast()来解释所有模板参数

cast<int, 2, float>(a);

如果您将ToT 放在首位,则必须仅显式显示它并让编译器从参数中推断出FromT 和Dim

cast<float>(a);

【讨论】:

  • 感谢您的建议。对我来说,关键是我必须把 ToT(to-type)放在第一位。我这样做了,它解决了我的问题。任何见解为什么我必须把它放在拳头位置?
  • “拳头位置”:(?和平与爱,南!(对不起:我在开玩笑;但我已经修改了我的答案,试图回答你的最后一个问题)。
猜你喜欢
  • 2014-01-02
  • 2016-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-23
  • 1970-01-01
  • 2023-03-13
  • 2011-02-24
相关资源
最近更新 更多