在类模板中重载赋值运算符,可以转换为另一个模板类型

问题描述 投票:0回答:3
#ifndef NUMBER_HPP
#define NUMBER_HPP

template <class T>
class Number
{
public:
  Number( T value ) : m_value( value )
  {
  }

  T value() const
  {
    return m_value;
  }

  void setValue( T value )
  {
    m_value = value;
  }

  Number<T>& operator=( T value )
  {
    m_value = value;
  }

  //  template <class T2>
  //  Number<T2>& operator=( const Number<T>& number )
  //  {
  //    m_value = number.value();

  //    return *this;
  //  }

private:
  T m_value;
};

typedef Number<int> Integer;
typedef Number<float> Float;
typedef Number<double> Double;

#endif // NUMBER_HPP

注释的赋值运算符重载是我尝试做我想做的事情,我认为它可能提供比代码片段上面的更好的描述。

我希望能够做到以下几点:

Float a(10);
Integer b(20);

a = b;

其中

a
然后将被转换为
int
并赋予
b
的值,但仍然是类
Number
的实例。

可能吗?你能帮我一下吗?

提前致谢。

c++ templates casting
3个回答
11
投票

你应该这样做:

template <class T2>
Number<T>& operator=( const Number<T2>& number )
{
    m_value = number.value();
    return *this;
}

也就是说,在参数类型中使用

T2
,而不是在返回类型中!

我宁愿使用不同的字母作为模板参数:

template <class U>
Number<T>& operator=( const Number<U>& number )
{
    m_value = number.m_value; //I would also directly access the member variable!
    return *this;
}

我认为,如果你想使用类类型作为模板参数并且其构造函数已声明,最好使用显式强制转换

explicit

 m_value = static_cast<T>(number.m_value); 

顺便说一下,另一个

operator=
应该实现为:

Number<T>& operator=(T const & value ) //accept by const reference
{
    m_value = value;
    return *this; //you've to return!
}

5
投票

您将一些

T
放错了位置。应该是

template <class T2>
Number<T>& operator=( const Number<T2>& number )
{
    m_value = number.value();
    return *this;
}

这会让你做到

Integer a(4);
Float b(6.2f);

a = b;

cout << a.value() << endl;

并且它将打印

6
,其行为类似于您正在模仿的
int
float
类型。


0
投票

如果您想要更多内置感觉,可以用赋值和强制转换来替换 value() 和 setValue():

#include <stdio.h>
#include <stdint.h>
#include <iostream>

template <class T>
class Number
{
public:
    Number<T>() : m_value( 0 ) { }
    Number<T>( T value ) : m_value( value ) { }
    
    Number<T>& operator=( T value )
    {
        m_value = value;
        return *this;
    }

    template <class T2>
    Number<T>& operator=( const Number<T2>& in )
    {
        m_value = static_cast< T >( in );
        return *this;
    }
    
    operator int() const
    {
        return m_value;
    }

    operator float() const
    {
        return m_value;
    }

    friend std::ostream& operator<<( std::ostream& s, Number<T>& in )
    {
        s << static_cast< T >( in );
        return s;
    }

private:
    T m_value;
};

typedef Number<int> Integer;
typedef Number<float> Float;
typedef Number<double> Double;

int main()
{
    Integer a[5] = { 0, 1, 2, 3, 4 };
    Double b(3);
    
    a[0] = 1;
    b = 2;
    b = a[0];
    
    std::cout << "b is " << b << std::endl;
    std::cout << "a[3] is " << a[3] << std::endl;

    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.