2016-11-14 5 views
0

セットアップのexistanceに応じて、異なる機能の実装を提供する:クラスclassA、及びclassAを使用しているクラスclassBあります。残念ながら、classBをプログラミングすると、classAに特定のメンバーsomeMemberがあるかどうかわかりません。それに応じて、classBのメンバー関数someFunctionは、どちらか一方の方法で実装されます。片方向がsomeMemberを使用しているので、someMemberclassAのメンバーではない場合、この関数インスタンスがコンパイルされないことが重要ですです。C++ 98:メンバ

質問:マクロ/定義とは別に、C++ 98の最適な解決策は何ですか?

MWE:

class classA 
{ 
public: 
    // c'tor 
    classA() 
    { 
     //someMember = 3; 
    }; 
    // does not have the member "someMember" 
    //int someMember; 
}; 

class classB 
{ 
public: 
    // only compile this function if "someMember" is a member of classB 
    int someFunction(classA a) 
    { 
     return a.someMember; 
    } 
    // ...and compile this one otherwise 
    int someFunction(classA a) 
    { 
     return 2; 
    } 
}; 

// --- just to have an MWE: --- 
#include<iostream> 
int main() 
{ 
    classA a; 
    classB b; 
    cout << b.someFunction(a); 
    return 0; 
} 
+1

「classAにsomeMemberかsomeMemberがあるかどうかわかりませんn 'classB'はあなたの実際のコードのテンプレートであり、' classA'はテンプレートのパラメータですか? – TartanLlama

+0

いいえ、つまり、 'classA'のバージョンが異なっていて、' classA'のバージョンによって 'someMember'が使用されているかどうかに依存します。これは互換性と構成上の問題です。 'classA'は私の(' classB')ソフトウェアコンポーネントと異なるバージョンで組み合わせることができる別のソフトウェアコンポーネントの中にあります。 – matheburg

+0

https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Member_Detector – acraig5075

答えて

2

ご質問がtemplatesタグ付けされているとおり、私はあなたのclassBが実際にクラステンプレートであるか、または少なくともそれがいずれかを使用することができます...これはあなたがSFINAEを適用できる場合であれば想定します例えば(あなたがC++ 98を使用している場合)を使用すると、より多くの幸運追加の形質などを使用しようとしてしまうかもしれません。この場合

#include <iostream> 
#include <type_traits> 

class classA 
{ 
public: 
    // c'tor 
    classA() 
    { 
     someMember = 3; 
    }; 
    // does not have the member "someMember" 
    int someMember; 
}; 

template<class T, class = void> 
class classB_impl 
{ 
public: 
    // ...and compile this one otherwise 
    int someFunction(T) 
    { 
     return 2; 
    } 
}; 

template <class T> 
class classB_impl<T, decltype(std::declval<T>().someMember, void())> { 
public: 
    // only compile this function if "someMember" is a member of classB 
    int someFunction(T a) 
    { 
     return a.someMember; 
    } 
}; 

using classB = classB_impl<classA>; 

int main() { 
    classB b; 
    std::cout << b.someFunction(classA{}) << std::endl; 
} 

[live demo]


:以下の溶液を使用して

#include <iostream> 

class classA 
{ 
public: 
    // c'tor 
    classA() 
    { 
     someMember = 3; 
    }; 
    // does not have the member "someMember" 
    int someMember; 
}; 

template <class T, int T::*V = &T::someMember> 
struct someMemberTrait { 
    typedef void type; 
}; 

template<class T, class = void> 
class classB_impl 
{ 
public: 
    // ...and compile this one otherwise 
    int someFunction(T) 
    { 
     return 2; 
    } 
}; 

template <class T> 
class classB_impl<T, typename someMemberTrait<T>::type> { 
public: 
    // only compile this function if "someMember" is a member of classB 
    int someFunction(T a) 
    { 
     return a.someMember; 
    } 
}; 

typedef classB_impl<classA> classB; 

int main() { 
    classB b; 
    std::cout << b.someFunction(classA()) << std::endl; 
} 

[live demo]

+0

あなたの迅速な対応に感謝します。残念ながら、あなたはそれを信じません、我々はまだC++ 98標準を使用しています。私が知る限り、 'decltype'はそこでは利用できません。 – matheburg

+1

@matheburg私の編集を参照してください –

+0

ありがとう、それは働いている! – matheburg

関連する問題