c++ - 编译时可配置回调

标签 c++ templates variadic-templates

我正在尝试为同步/异步调用行为实现编译时可配置回调。

这是第一种方法:

//emit type's
enum EEmitType
{
   SYNC,
   ASYNC,
};

//general 
template<EEmitType et, typename... Args>
class callback_impl;

//implementation
template<EEmitType et, typename R, typename... Args>
class callback_impl<et, R(Args...)>
{ /*todo*/ };

//................................................................

//convert enum value to type or SFINAE
template <EEmitType et>
using callback_emit_type = std::integral_constant<EEmitType, et>;

//(for default SYNC)
template <typename T>
struct is_emit_type : std::false_type {};

//(for any other implementation)
template <EEmitType et>
struct is_emit_type<callback_emit_type<et>> : std::true_type {};

//................................................................

//metafunction
template <typename T>
using is_emit_type_t = typename is_emit_type<T>::type;

//................................................................

//for decl. like: callback<void()>
template <typename _unused, typename... Args>
struct construct_callback_impl
{
    //alias on implementation
    using type = callback_impl<SYNC, Args...>;
};

//for decl. like: callback<callback_emit_type<ASYNC>, void()>
template <typename EEmitType, typename... Args>
struct construct_callback_impl<typename 
std::enable_if<is_emit_type_t<EEmitType>::value>::type, EEmitType, Args...>
{
    //alias on implementation
    using type = callback_impl<EEmitType::value, Args...>;
};

//................................................................

//user alias
template <typename... Args>
using callback = typename construct_callback_impl<Args...>::type;

正在使用:

callback<int(int)> ff_s; //<--  uses undefined class 'callback_impl<SYNC>'
callback<callback_emit_type<ASYNC>, int(int)> ff_a; //<--OK

当然因为 first args is eating,为了成功编译应该这样写:

 callback<int(int), int(int)> ff_s 

但这当然不是 Not Acceptable 。 好的,然后我尝试从 Args 中提取 EEmitType...

//for decl. like: callback<void()>
template <typename... Args>
struct construct_callback_impl
{
   //alias on implementation
   using type = int; //temporary stub
};

//for decl. like: callback<callback_emit_type<ASYNC>, void()>
template <typename... Args>
struct construct_callback_impl<typename std::enable_if<is_emit_type_t< typename std::tuple_element_t<0, std::tuple<Args...> >::type >::value>::type, Args...>
{
    //alias on implementation
    using type = int; //temporary stub
};

但现在我明白了:

error C2338: tuple index out of bounds
note: see reference to class template instantiation 'std::tuple_element<0,std::tuple<>>' being compiled

最佳答案

像这样的东西应该可以工作

template <typename>
struct emit_type_value : std::integral_constant<EEmitType, SYNC> {};

template <EEmitType x>
struct emit_type_value<callback_emit_type<x>> : std::integral_constant<EEmitType, x> {};

//for decl. like: callback<void()>
template <typename Arg0, typename ... Args>
struct construct_callback_impl
{
    //alias on implementation
    using type = std::conditional_t<is_emit_type<Arg0>::value,
          callback_impl<emit_type_value<Arg0>::value, Args...>,
          callback_impl<SYNC, Arg0, Args...>>;

};

如果您只使用 falsetrue 而不是 SYNCASYNC 会更简洁一些。

关于c++ - 编译时可配置回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52061158/

相关文章:

c++ - 可变参数模板,编译器道歉

c++ - 如何对参数包进行分组或配对折叠?

c# - 什么是C(COM)中的接口(interface)它和C#中的接口(interface)一样吗

c++ - 检测容器是否具有迭代器类型

c++ - 如何正确使用动态数组?

c++ - 通过头文件函数将二叉搜索树中遍历的数据加载到Vector中

c++ - 是否可以根据类型是整数类型还是浮点类型来重载模板函数?

c++ - 将参数转发给模板成员函数

c++ - 使用带有 unique_ptr 的 union

C++ 构造函数初始化列表在 C 中的替代方案?