C++のテンプレートは非変か

C++のテンプレートって非変なんですかね?

ここでの議論がちょっと気になった。


上の記事のコメ欄で

template <class T>
class Hoge
{
public:
  Hoge() { }
  template<class U>
  Hoge(const Hoge<U>&) { }
  template<class U>
  Hoge& operator=(const Hoge<U>&) { return *this; }
};

こう書いてしまえば、異なるテンプレート型でも代入できるという意見があったのだけど、暗黙の型変換を許可してよいのならScalaでも

class Hoge[T]{}

implicit def convHoge[T,U](a:Hoge[U]):Hoge[T]={
  // ... Hoge[T]を返す.
}

こう書いてしまえば同じ事が実現できてしまう。
結局のところ間に型変換をはさむと新たに目的の型のオブジェクトを生成してしまうので、新たなオブジェクトの生成なしに代入等ができる共変や反変とは別物だといってよいのではないかと。
翻ってC++のテンプレートはやはり非変といってよい気がするのですがどうでしょうか。


追記(2010/08/07): 元のコメ欄でも指摘いただきましたが、たしかにこれをもってC++のテンプレートは非変というのは言い過ぎです。ここでいいたかったのはC++での暗黙の型変換とscalaにおける非変+inplicit conversionが同等とみなせるならC++のテンプレートはScalaにおける非変指定と同じとみなしてよいのでは、程度の主張でした。だたし、暗黙の型変換使わずとも共変・反変にできるかもというコメントもあったので、続報期待しつつ自分でも可能な限り調べてみようかと…