If you upgrade to Boost 1.54, there is a nice library called TTI. It allows you to compose type traits introspection meta functions at will, so that you can easily spin off you own meta predicates which can be used to enable or disable function templates. Though it is a nice meta programming exercise, I don't recommend to do that in production code. I found it hard to catch the "false negatives" which arise from implementation details of STL containers. For example, the associative containers coming with MSVC11 inherit their begin
and end
member functions from a base class which yields false negative with meta predicates generated via BOOST_TTI_HAS_MEMBER_FUNCTION
. Despite of his nickname, Useless gave you a good advice: Use concepts coming with Boost.Range to reject or accept the type inside the body of the function template such as the constructor in your example... Of course, this will not solve the convertibility problem for your Constructor
...
EDIT: example, taken from 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
}