0

私は次のようなことをしたいと思います:

class A {
  public:
    void f();
  private:
    void g() { };
};

class B {
  public:
    void f();
  private:
    void g() { };
};

template<typename T>
void T::f() {
    g();
}

int main() {
    A a;
    B b;
    a.f();
    b.f();
}

ただし、T :: f()はコンパイルされません。

考えられる回避策は、f()を非メンバーにすることです。

template<typename T>
void f(T* t);

またはCRTPを使用する:http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern

しかし、上記のように行うC ++構文はありませんか?

編集:コードが2つのクラスAとBで共有されている大きな関数f()があります。AとBは、f()が使用する同じインターフェイスを持っています。ただし、ランタイムポリモーフィズム(つまり、仮想関数)を使用していないため、f()のコーパスはコンパイル時に2回インスタンス化する必要があります。1回はA用、もう1回はB用です。テンプレートはまさにこの目的のために作成されます。私の場合、関数f()は、テンプレートタイプが*thisのタイプであるテンプレート関数である必要があります。

4

2 に答える 2

2

フリー関数が正解です。とにかく、この正確な理由から、メンバー関数よりもフリー関数を優先する必要があります。クラスに侵入することなくインターフェイスを拡張します。

この場合、制約のないテンプレートを使用した無料の関数は少し醜いです。これは、すべてのケースではなく、2つのケースでのみ機能する必要があるためです。次のようなことをする必要があります。

namespace detail
{
    template <typename T>
    void f(T* t)
    {
        // implement stuff
    }
}

void f(A* x)
{
    detail::f(x);
}

void f(B* x)
{
    detail::f(x);
}

これで、オーバーロードを介してその関数へのアクセスを制限できます。

于 2012-08-23T02:20:27.170 に答える
1

instance.f()これは、free関数を使用して構文を保持する例です。プライベートメソッドにアクセスするには、関数をフレンドとしてマークする必要があります。

#include <iostream>

namespace details
{
    template<class T>
    static void f_impl(T* _this)
    {
        _this->g();
    }
}

class A {
public:
    template<class T> friend void details::f_impl(T*);
    void f()
    {
        details::f_impl(this);
    }
private:
    void g()
    {
        std::cout << "A" << std::endl;
    }
};

class B {
public:
    template<class T> friend void details::f_impl(T*);
    void f()
    {
        details::f_impl(this);
    }
private:
    void g()
    {
        std::cout << "B" << std::endl;
    }
};

int main() {
    A a;
    B b;
    a.f();
    b.f();
}
于 2012-08-23T02:49:33.703 に答える