【问题标题】:template class conversion with two parameters带两个参数的模板类转换
【发布时间】:2021-08-18 15:38:23
【问题描述】:

我在将类型名称相同但大小不同的模板类转换为相同的模板类时遇到问题。让我用代码解释一下:

template<typename T, int SIZE>
class Array
{
  T aData[SIZE];
  friend Array operator+(Array &arr1, Array &arr2);
};

这就是我所拥有的模板类。假设我已经超载了operator+

所以这就是我想做的:

Array<double, 10> a1;
Array<double, 20> a2;
a1 + a2;

我知道a1a2 是不同的类。所以我的问题是,如何将a2 转换为Array&lt;double, 10&gt;?我想用一个构造函数来做到这一点,它接受Array&lt;T, SIZE2&gt; 的对象并返回Array&lt;T, SIZE&gt; 的对象。这是可行的吗? 更笼统地说:我想将Array&lt;T, SIZE2&gt; 转换为Array&lt;T, SIZE&gt; 的类。

【问题讨论】:

  • Array&lt;double,20&gt; 转换为Array&lt;double,10&gt; 意味着什么?当数组大小不同时,您要么丢失必须填充空白的信息。如果那是你真正想做的,你需要解释这种转换应该如何工作

标签: c++ class templates


【解决方案1】:

正确的解决方案是使operator + 成为可以处理不同类型的两个参数的模板。

#include <cstddef>

template
<
    typename x_Item
,   ::std::size_t x_size
>
class Array;

template
<
    typename x_Item
,   ::std::size_t x_left_size
,   ::std::size_t x_right_size
>
Array<x_Item, x_left_size + x_right_size>
operator +
(
    Array<x_Item, x_left_size> const & left
,   Array<x_Item, x_right_size> const & right
);

template
<
    typename x_Item
,   ::std::size_t x_size
>
class Array
{
    template
    <
        ::std::size_t x_left_size
    ,   ::std::size_t x_right_size
    >
    friend
    Array<x_Item, x_left_size + x_right_size>
    operator +
    (
        Array<x_Item, x_left_size> const & left
    ,   Array<x_Item, x_right_size> const & right
    );

    x_Item aData[x_size];
};


template
<
    typename x_Item
,   ::std::size_t x_left_size
,   ::std::size_t x_right_size
>
Array<x_Item, x_left_size + x_right_size>
operator +
(
    Array<x_Item, x_left_size> const & left
,   Array<x_Item, x_right_size> const & right
)
{
    // implementation...
}

【讨论】:

  • 难道没有办法重载operator+ 一次,然后将对象转换为我想要的类型,这样我就可以将它们加在一起了吗?
  • @auroNpls 您当然可以为此目的实现一个模板构造函数,接受不同大小的数组。但是在这里创建临时数组参数似乎很浪费。
  • 这就是我想要在这里实现的目标。这里有什么想法吗?我真的很感激
【解决方案2】:

一种方法是提供转换构造函数:

template<typename T, std::size_t SIZE>
class Array
{
public:

    Array() = default;
    Array(const Array&) = default;
    Array(Array&&) = default;
    
    template <std::size_t N>
    Array(const Array<T, N>&) requires (SIZE < N)  { /*..*/ }

    friend Array operator+(const Array &arr1, const Array &arr2) { /*..*/ }
};

Demo

  • requires 是 C++20,你之前可能会使用 SFINAE 技巧。
  • 您必须注意预期的转换以避免歧义: (您想让a1 + a2 解析为static_cast&lt;decltype(a2)&gt;(a1) + a2 还是a1 + static_cast&lt;decltype(a1)&gt;(a2)?)

【讨论】:

    猜你喜欢
    • 2019-11-10
    • 1970-01-01
    • 2018-02-16
    • 2011-08-25
    • 2021-09-02
    • 2012-12-07
    • 1970-01-01
    • 2017-01-16
    • 1970-01-01
    相关资源
    最近更新 更多