如何在 c++ 中从一个相关类分配到另一个相关类、自定义分配或强制转换?

How to assign from one to another related class, custom assignment or cast in c++?

提问人:Kostas 提问时间:10/24/2022 最后编辑:Kostas 更新时间:10/25/2022 访问量:89

问:

我有一个以浮点类型为模板的类,

template <typename fl_t> class generic {
fl_t a,b;
/// a bunch of getters and setters, etc...
}

并使用 float 和 double 进行实例化

typedef generic<double> dmatrix;
typedef generic<float>  fmatrix;

后来,当我想将 fmatrix 分配给 dmatrix 时,我得到

error: no viable conversion from 'const generic<float>' to 'generic<double>'
note: candidate constructor (the implicit copy constructor) not viable: 
no known conversion from 'const fmatrix' (aka 'const generic<float>') 
to 'const generic<double> &' for 1st argument

template <typename fl_t> class generic {

我写了一个超载的作业:

template <typename f> generic<f>& operator= ( const generic& g){
    aSET(g.aGET(); // etc
    return *this;
}

这编译了问题,但不能解决问题。为什么?我必须写一个演员表,用什么签名吗?

编辑:我接受了答案,但对于实际工作,似乎也经常需要演员。可以看到如何做到这一点:

template <typename fl_t> class generic {
public:
fl_t a;
  double aGET() const {return double(a);}
  void aSET(double x) { a=fl_t(x);}

  template <typename f> generic& operator=(const generic<f>& g){ // assignment
      aSET( g.aGET() );
      return *this;
  }
    
  template <typename f> operator generic<f>() { // constructor
      generic<f> m;   
      m.aSET( aGET() );
      return m;
  }

};

typedef generic<double> dmatrix;
typedef generic<float> fmatrix;

dmatrix fn(fmatrix m){
    dmatrix d=m; // uses constructor, operator()
    d=m;         // uses assignment, operator=
    return d;
}
C++ 强制转换 赋值运算符

评论

1赞 Nelfeal 10/24/2022
你是想写(参数)吗?const generic<f>& g
0赞 Kostas 10/24/2022
@Nelfeal我想不是,因为我想从一种类型分配到另一种类型。这行得通吗?模板 <typename d, typename f> generic<d>& operator= ( const generic<f>& g)
0赞 perivesta 10/24/2022
您不是会员吗?它可能应该是,然后您可以在其他一些上额外模板化它:operator=generic<fl_t>Ftemplate<typename F> generic<fl_t>& operator=(const generic<F>& other)
0赞 Nelfeal 10/24/2022
@perivesta 赋值运算符不能是非成员。

答:

2赞 Nelfeal 10/24/2022 #1

赋值运算符将当前类型作为参数:

template <typename fl_t> class generic {
// ...
    template <typename f> generic<f>& operator=(const generic& g)
//                                this is generic<fl_t> ^^^^^^^ 
// ...
};

如果要从其他类型分配,则需要交换返回类型和参数类型:

template <typename f> generic& operator=(const generic<f>& g)

参数的类型是要从中分配的变量的类型。返回类型可以是您想要的任何类型,但对于赋值运算符,它通常是对要赋值到的变量类型(即当前类)的引用,以便您可以直接对结果执行其他操作,例如链赋 ()。a = b = c

如果不希望转换是隐式的(换句话说,如果希望赋值需要强制转换),则可以将运算符标记为显式:

template <typename f> explicit generic& operator=(const generic<f>& g)

评论

0赞 Kostas 10/24/2022
谢谢!我会接受的。在这种情况下,你是否愿意详细说明写一个演员表是否更好?
1赞 MSalters 10/24/2022
@Kostas:没有单一的答案;这取决于类型。我想你想在和没有强制转换之间进行转换,当且仅当你可以从转换到没有强制转换时。generic<A>generic<B>AB
0赞 Caleth 10/24/2022
@Kostas“写演员表”是什么意思?你的意思是显式构造函数吗?
0赞 Kostas 10/25/2022
@Caleth,是的,最终我也不得不这样做。没有它,像 dmatrix d=f 这样的初始化就不起作用。
0赞 Nelfeal 10/25/2022
@Kostas 初始化与赋值不同。为此,您需要一个构造函数。