Boost 1.54 にアップグレードすると、TTI という素敵なライブラリがあります。型特性イントロスペクション メタ関数を自由に作成できるため、関数テンプレートを有効または無効にするために使用できる独自のメタ述語を簡単にスピンオフできます。これは優れたメタ プログラミングの演習ですが、製品コードでこれを行うことはお勧めしません。STL コンテナーの実装の詳細から生じる「偽陰性」を見つけるのが難しいことがわかりました。たとえば、MSVC11 に付属する連想コンテナーは、基本クラスからそれらの関数begin
とend
メンバー関数を継承します。BOOST_TTI_HAS_MEMBER_FUNCTION
. 彼のニックネームにもかかわらず、Useless は良いアドバイスをくれました: Boost.Range に付属する概念を使用して、例のコンストラクターなどの関数テンプレートの本体内の型を拒否または受け入れます... もちろん、これは問題を解決しませんあなたの変換可能性の問題Constructor
...
編集: 例、vexから取得:
#include <boost/tti/has_member_function.hpp>
#include <vector>
#include <map>
namespace tti_test {
BOOST_TTI_HAS_MEMBER_FUNCTION(begin);
// .. begin test class for mstest
// this succeeds in both variants
TEST_METHOD(has_const_member_function_begin_is_true_for_vector)
{
Assert::IsTrue(has_member_function_begin<
std::vector<int>::const_iterator (std::vector<int>::*)() const
>::value);
Assert::IsTrue(has_member_function_begin<
const std::vector<int>, std::vector<int>::const_iterator
>::value);
}
// this fails in both variants...
TEST_METHOD(has_const_member_function_begin_is_true_for_map)
{
Assert::IsTrue(has_member_function_begin<
std::map<int, int>::const_iterator (std::map<int, int>::*)() const
>::value);
Assert::IsTrue(has_member_function_begin<
const std::map<int, int>, std::map<int, int>::const_iterator
>::value);
}
// end test class for mstest
}