14

私は非常に単純な問題を抱えています:どこかに関数があります

int size (const C & c)

これは、少なくとも引数依存の名前検索によって見つかります。今問題:

struct B
{
    int size () { /* ... */ }

    void doSomething (const C & c)
    {
       int x = size (c); // <----------- problem!
       // ...
    }
}

メンバー関数が見つかった後に名前の検索が停止するため、これは機能しません。

メンバー関数が呼び出されようとするのではなく、メンバー関数が存在しない場合にコンパイラが行うことを行うように、指定された行に何を書く必要がありますか?

これは、引数に依存する名前の検索を防ぎ、宣言ている場所がわかっている場合にのみ機能するためです。::sizesize

さらなる複雑さ:

T以下のテンプレート化されたメンバー関数を使用する関連する型ごとB::doSomethingに、どこかに関数があることを知っています

int size (const T & t)

これは、少なくとも引数依存の名前検索によって見つかります。B次のようになります。

struct B
{
    int size () { /* ... */ }

    template<class T>
    void doSomething (const T & t)
    {
       int x = size (t); // <----------- problem!
       // ...
    }
}

非メンバー関数を呼び出したいです (存在することは確かですが、どこにあるかはわかりません)。

4

3 に答える 3

6

独自のメンバー関数の名前を変更できない場合は、汚いトリックを使用できます。

static inline int dirty_trick(C const & c)
{
    return size(c);
}

void B::doSomething(C const & c)
{
    int x = dirty_trick(c);

    // ...
}
于 2012-11-15T22:19:07.027 に答える
3

完全を期すために、Richard Smith によって受け入れられた回答に追加します。

私のソリューションは次のようになります。

namespace adl {
   // This declaration's only purpose is the possibility to refer to
   // a non-member function named "size" in a using declaration.
   //
   // The signature does not matter, so we choose the easiest possible one.
   void size ();
}

struct B
{
    int size () { /* ... */ }

    template<class T>
    void doSomething (const T & t)
    {
       using adl::size;
       int x = size (t); // <----------- no problem anymore
       // ...
    }
};

このようにして、実際には必要のないヘッダーを含める必要はありません。

于 2015-08-20T19:50:57.683 に答える