Yes in C++11, SFINAE was extended to expressions, so you can define a trait like is_t_extension
to detect for the presences of the member functions, like this:
template<class... T>
struct holder
{
typedef void type;
};
template<class T, class=void>
struct is_t_extension
: std::false_type
{};
template<class T, class=void>
struct is_t_extension<T, typename holder<
decltype(std::declval<T>().getRequestId),
decltype(std::declval<T>().getDirection),
decltype(std::declval<T>().getDriveWay),
decltype(std::declval<T>().getCycleId)
>::type>
: std::true_type
{};
Now this just checks for their presence. With some work you could extend the above to detect valid signatures, or you could use the Tick library to write the trait instead, which looks a lot cleaner:
TICK_TRAIT(is_t_extenstion)
{
template<class T>
auto requires_(T&& x) -> TICK_VALID(
returns<unsigned long>(x.getRequestId),
returns<eDirection>(x.getDirection),
returns<eDriveWay>(x.getDriveWay),
returns<unsigned long>(x.getCycleId)
);
};
Then in your class you could just use a static_assert
to report the error:
template <typename TExtension>
class foo
{
static_assert(is_t_extension<TExtension>(), "Not a TExtension");
};
Or if you want to allow for specializations, you can use TICK_CLASS_REQUIRES
:
template <typename TExtension, class=void>
class foo;
template <typename TExtension>
class foo<TExtension, TICK_CLASS_REQUIRES(is_t_extension<TExtension>())>
{
...
};