使用带有 static_assert 的类型别名缩小模板中允许的类型
Narrow down allowed types in templated using type alias with static_assert
在学习基于模板的元编程时,我遇到了以下问题:
我有一个使用类型别名的模板,我想使用 static_assert
缩小允许的类型,但我不确定如何编写它:
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");
此方法失败,因为 service_loop
未在 static_assert
的范围内声明。检查 classes 时,我可以将断言移动到 class 范围内,但是这里的语法是什么?
您可以编写一个助手 class 来完成 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;
另请注意,它应该是 std::is_convertible<T,U>::value
或 std::is_convertible<T,U>{}
而不是 std::is_convertible<T,U>.value
。尽管我们可能会在 C++17 中获得 std::is_convertible_v<T,U>
辅助变量模板。
在学习基于模板的元编程时,我遇到了以下问题:
我有一个使用类型别名的模板,我想使用 static_assert
缩小允许的类型,但我不确定如何编写它:
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");
此方法失败,因为 service_loop
未在 static_assert
的范围内声明。检查 classes 时,我可以将断言移动到 class 范围内,但是这里的语法是什么?
您可以编写一个助手 class 来完成 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;
另请注意,它应该是 std::is_convertible<T,U>::value
或 std::is_convertible<T,U>{}
而不是 std::is_convertible<T,U>.value
。尽管我们可能会在 C++17 中获得 std::is_convertible_v<T,U>
辅助变量模板。