3

テンプレート初心者です。質問がありました。特殊化されていない (またはジェネリックな) 型をパラメーターとしてクラス メンバー関数を特殊化する方法はありますか。つまり、次のプログラムの U1 と U2 は U1 型の boost::shared_ptr であり、T1 と T2 は通常の型です。

#include <iostream>

template <typename T1, typename T2>
class X {
    public:
    template <typename U1, typename U2>
    void get_as(U1& source, U2& dest);
};

class Y {
};

template<> template<>
void
X<int, int>::get_as<double, double>(double& source, double& dest) {
    std::cout << "SOURCE IS " << source << std::endl;
    std::cout << "DESTINATION IS " << dest << std::endl;
}

template<> template<>
void 
X<int, int>::get_as<shared_ptr, shared_ptr>(shared_ptr<Y>& source, shared_ptr<Y>& dest) {
//some logic
}


int main()
{
    double d1 = 1.0;
    double d2 = 1.1;
    X<int, int> x;
    x.get_as(d1, d2);
    shared_ptr<Y> p1(new Y());
    shared_ptr<Y> p2(new Y());
    x.get_as(p1, p2); //Would this work?

    return 0;
}

私はそれを読んでみましたが、それができるかできないかがはっきりとわかりました。

4

1 に答える 1

1

テンプレート引数に表示される shared_ptr は完全な型ではないため、例のコードはコンパイルされません。機能させるには、次のように関数を変更できます。

template<> template<>
void
X<int, int>::get_as<shared_ptr<Y>, shared_ptr<Y> >(shared_ptr<Y>& source, shared_ptr<Y>& dest) {
//some logic
}

しかし、これはあなたが探している一般性ではないかもしれません。残念ながら、次のことはできません

template<> template<typename T>
void
X<int, int>::get_as<shared_ptr<T>, shared_ptr<T> >(shared_ptr<T>& source, shared_ptr<T>& dest) {
//some logic
}

これは、テンプレート化されたクラスのメンバー関数の部分的なテンプレートの特殊化です。C++ では、このようなことは禁止されています。ただし、テンプレートとテンプレートの特殊化についてすべて学習すると、古き良き関数のオーバーロードがまだ利用可能であることを忘れがちです。次のコードは、期待どおりに機能します

class Y {
};

class Z {
};

template <typename T1, typename T2>
class X {
    public:
    template <typename U1, typename U2>
    void get_as(U1& source, U2& dest);

    template <typename U>
    void get_as(shared_ptr<U> source, shared_ptr<U> dest);

    void get_as(shared_ptr<Y> source, shared_ptr<Y> dest);
};



template<> template<>
void
X<int, int>::get_as<double, double>(double& source, double& dest) {
    std::cout << "SOURCE IS " << source << std::endl;
    std::cout << "DESTINATION IS " << dest << std::endl;
}

template <typename T1, typename T2>
template <typename U>
void X<T1, T2>::get_as(shared_ptr<U> source, shared_ptr<U> dest)
{
  std::cout << "Overloaded member" << std::endl;
}

template <typename T1, typename T2>
void X<T1, T2>::get_as(shared_ptr<Y> source, shared_ptr<Y> dest)
{
  std::cout << "Special overloaded member" << std::endl;
}

int main()
{
    double d1 = 1.0;
    double d2 = 1.1;
    X<int, int> x;
    x.get_as(d1, d2);
    shared_ptr<Y> p1(new Y());
    shared_ptr<Y> p2(new Y());
    x.get_as(p1, p2); //Would this work?

    shared_ptr<Z> p3(new Z());
    shared_ptr<Z> p4(new Z());
    x.get_as(p3, p4); //Would this work?

    return 0;
}

出力は

SOURCE IS 1
DESTINATION IS 1.1
Special overloaded member
Overloaded member
于 2012-07-16T12:13:09.050 に答える