以下の C++ ソースコードにおいて

template<typename _t_type_>
class OuterClass {
public:
    class InnerClass;
};

template<typename _t_type_>
class OuterClass<_t_type_>::InnerClass
{
public:
    InnerClass() { }

    template<typename _t_type2_>
    InnerClass(const typename OuterClass<_t_type2_>::InnerClass& _a_InnerClass_) {  }
};

struct foo { };
struct bar { };

int main()
{
    OuterClass<foo>::InnerClass o1;
    OuterClass<bar>::InnerClass o2 = o1; // error: no viable conversion from 'OuterClass<foo>::InnerClass' to 'OuterClass<bar>::InnerClass'
}

OuterClass<bar>::InnerClass o2 = o1; がエラーとなります。

    template<typename _t_type2_>
    InnerClass(const typename OuterClass<_t_type2_>::InnerClass& _a_InnerClass_) {  }

において _t_type_bar, _t_type2_foo となって解決されることを期待したのですが、期待通りではありませんでした。 clang++, g++ の両方でコンパイルしたのですが同じ結果でした。

やりたいことは任意の typename T に対し

    OuterClass<T>::InnerClass

となって、 任意の typename T1 と任意の typename T2

    OuterClass<T1>::InnerClass と OuterClass<T2>::InnerClass

のコピーコンストラクタが成り立つようにしたいためです。

  • 質問1: なぜこれは解決できないでエラーとなるのでしょうか。
  • 質問2: エラーがでないようにするには、どうしたらいいでしょうか。

参考までに

    OuterClass<bar>::InnerClass o2 = o1

をコメントアウトすることで、 InnerClass() { } は期待どおりに機能します。