paladin324
paladin324

Reputation: 342

Appending to every arg in variadic C macro

I'm trying to create a macro that works like the "where" constraint in higher-level languages:

#define where(T, ...) typename std::enable_if< /* tricky part */ >::type 
// should expand like so: trait1<T>::value && trait2<T>::value ... traitN<T>::value

So that VA_ARGS is list of traits and is used like so:

template<class T,
    where(T, std::is_default_constructible, std::is_class)>
class A { };

Is that possible?

Upvotes: 0

Views: 122

Answers (2)

paladin324
paladin324

Reputation: 342

I am sorry to bring this question back from the dead after four years, but I think I have a better answer that does exactly what I was aiming for at the time. (Not needing to specify the argument for the predicates multiple times.)

template <typename T, template <typename> class... Predicates>
using where_t = std::enable_if_t<std::conjunction_v<Predicates<T>...>>;

template <typename T, typename = where_t<T, std::is_default_constructible, std::is_class>>
struct my_struct
{
};

Upvotes: 0

Kerrek SB
Kerrek SB

Reputation: 477580

Maybe something like this:

#define WHERE(P, ...) join_predicate<P, __VA_ARGS__>::value

template <template <typename> typename Pred, typename ...Args>
struct join_predicate : std::conjunction<Pred<Args>...> {};

Usage:

std::enable_if_t<WHERE(std::is_default_constructible, Foo, Bar, Quz), int>

I would probably not even bother with the macro and just use a real C++ construct, maybe:

template <template <typename> typename P, typename ...Args>
constexpr bool where_v = join_predicate<P, Args...>::value;

Upvotes: 1

Related Questions