【问题标题】:Narrow down allowed types in templated using type alias with static_assert使用带有 static_assert 的类型别名缩小模板中允许的类型
【发布时间】:2016-01-12 18:25:37
【问题描述】:

在学习基于模板的元编程时,我遇到了以下问题: 我有一个使用类型别名的模板,我想用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 的范围内声明。检查类时,我可以将断言移动到类范围内,但是这里的语法是什么?

【问题讨论】:

  • 我不确定我是否理解。你的意思是用不能转换为这些类型的东西来实例化service_functionality_t 应该会失败吗?
  • @TartanLlama 完全正确

标签: c++ templates c++11 static-assert


【解决方案1】:

您可以编写一个帮助类来执行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&lt;T,U&gt;::valuestd::is_convertible&lt;T,U&gt;{},而不是std::is_convertible&lt;T,U&gt;.value。虽然我们可能会在 C++17 中获得 std::is_convertible_v&lt;T,U&gt; 辅助变量模板。

Live Demo

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多