Superlokkus
Superlokkus

Reputation: 5069

Narrow down allowed types in templated using type alias with static_assert

While still learning template based meta programming, I've come to the following problem: I've got a templated using type alias, and I want to narrow down the allowed types with static_assert but I'm not sure how to write it:

using service_func_plain_loop_t = std::function<void(void)>;
using service_func_with_arg_loop_t = std::function<void(std::string)>;
using service_callbacks_t = std::map<event, std::function<bool(void) >>;

template<typename service_loop> using service_functionality_t =
std::pair<service_loop, service_callbacks_t>;
static_assert(
        std::is_convertible<service_loop,service_func_plain_loop_t>.value ||
        std::is_convertible<service_loop,service_func_with_arg_loop_t>.value,
        "service_loop has to be either service_func_plain_loop_t or " 
        "service_func_with_arg_loop_t");

This approach fails because of service_loop is not declared in the scope of static_assert. When checking classes I can just move the assert into the class scope, but what's the syntax here?

Upvotes: 1

Views: 163

Answers (1)

TartanLlama
TartanLlama

Reputation: 65770

You could write a helper class to do the static_assert:

template <typename service_loop>
struct service_functionality {
    static_assert(
        std::is_convertible<service_loop,service_func_plain_loop_t>::value ||
        std::is_convertible<service_loop,service_func_with_arg_loop_t>::value,
        "service_loop has to be either service_func_plain_loop_t or " 
        "service_func_with_arg_loop_t");

    using type = std::pair<service_loop, service_callbacks_t>;   
};

template<typename service_loop> using service_functionality_t =
typename service_functionality<service_loop>::type;

Note also that it should be std::is_convertible<T,U>::value or std::is_convertible<T,U>{} rather than std::is_convertible<T,U>.value. Although we'll likely get std::is_convertible_v<T,U> helper variable templates in C++17.

Live Demo

Upvotes: 1

Related Questions