Я столкнулся с аналогичной проблемой, желая пересылать конструкторы в базовый класс, когда аргументы совместимы, и делать что-то еще, когда нет.
Вот обобщенные черты, работающие на MSVC 2013 (требуется материал на C ++ 11):
namespace detail {
template<class type,class...Args>
class constructible_from
{
template<class C>
static C arg();
template <typename U>
static boost::mpl::true_ constructible_test(U *, decltype( U(arg<Args>()...) ) * = 0 );
static boost::mpl::false_ constructible_test(...);
public:
typedef decltype( constructible_test(static_cast<type*>(nullptr)) ) result;
};
} // namespace detail
template<class type>
struct constructible
{
template<class...Args>
struct from :
detail::constructible_from<type,Args...>::result {};
};
Вот пример использования черт, я оставляю приложение enable_if в качестве упражнения: D:
struct b{};
struct c{};
struct d : c{};
struct a
{
a() {}
a(a &) {}
a(b,c) {}
a(c) {}
};
static_assert(
constructible<a>::from<>::value,
"a()"
);
static_assert(
constructible<a>::from<a&>::value,
"a(a&)"
);
static_assert(
! constructible<a>::from<const a&>::value,
"a(const a&)"
);
static_assert(
constructible<a>::from<b,c>::value,
"a(b,c)"
);
static_assert(
! constructible<a>::from<b>::value,
"a(b)"
);
static_assert(
constructible<a>::from<c>::value,
"a(c)"
);
static_assert(
constructible<a>::from<d>::value,
"a(d)"
);