首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++11/14可变模板可以迭代函数的参数吗?

C++11/14可变模板可以迭代函数的参数吗?
EN

Stack Overflow用户
提问于 2015-06-16 14:45:49
回答 2查看 280关注 0票数 0

我使用各种模板来捕获Isis2中的静态类型信息,这是一个原子多播库(isis2.codeplex.com)。一些Isis2事件是通过upCall传递的。例如,如果您编码

代码语言:javascript
复制
Group g("myGroup");
g.Handlers[UDPATE] += [](string& name, Foo& f) { ... your code };
....
g.OrderedSend(UPDATE, "John Doe", new Foo(...));

然后,当接收到组g中带有字符串和Foo对象的更新的多播时,Isis2将构造Foo对象的本地实例,然后使用适当的参数向上调用此lambda。

这是我的谜题。我有不同的代码来扫描OrderedSend的参数,并且可以捕获构建我的消息所需的静态类型信息。最后,我传递真实的OrderedSend方法--一个一维的参数数组,每个数组都带有它的类型、指针或对数据或对象的安全引用,对于一个对象,传递一个封送方法的地址。但是要使用可变模板来扫描lambda,我需要查看函数的“内部参数列表”,也就是说要添加到处理程序向量中的对象是lambda: type_traits方法只会说它是一个类型为" function“的对象。我关注的是lambda的参数列表中的字符串和Foo类型。但据我所见,type_traits.h没有访问参数列表的任何东西。

GCC-11的一个特定选项是解压类型并解析结果字符串。但是,是否有一个不同的模板特性可以让我在编译时获得lambda的参数列表?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-06-17 02:38:25

代码语言:javascript
复制
template<class Sig>
struct MessageName {
  std::string name;
  MessageName() = delete;
  MessageName( std::string o ):name(o) {}
  MessageName(MessageName&&)=default;
  MessageName(MessageName const&)=default;
  MessageName& operator=(MessageName&&)=default;
  MessageName& operator=(MessageName const&)=default;
};

// trait to determine if some args are compatible:
template<class Sig, class...Ts>
struct is_compatible : std::false_type {};
template<>
struct is_compatible<void()> : std::true_type {};

template<class A0, class...Args, class T0, class...Ts>
struct is_compatible<void(A0, Args...), T0, Ts...>:
  std::integral_constant<bool,
    std::is_convertible<T0, A0>::value
    && is_compatible< void(Args...), Ts... >::value
  >
{};
struct HandlerMap {
  template<class Sig>
  void add_handler(
    MessageName<Sig> msg,
    block_deduction< std::function<Sig> > handler
  )
  {
    // ...
  }
  template<class Sig, class...Ts>
  typename std::enable_if<is_compatible<Sig, Ts...>::value>::type
  send_message( MessageName<Sig> msg, Ts&&... ts )
  {
    // ...
  }
};

UPDATE令牌应该是MessageName类型的。所有MessageName必须声明与它们相关的签名。

代码语言:javascript
复制
MessageName< void(std::string const&, Foo const&) > UPDATE{"update"};

就像上面提到的。

然后,当您添加一个处理程序时,对add_handler的调用将根据所需的签名检查分配的函数,并给出一个std::function

类似地,当您发送消息时,可以根据签名检查传递的类型。您甚至应该将参数转换为函数正文中的每个签名参数类型。

这将尽可能多地将类型检查移到编译时,这是很好的C++风格。

票数 1
EN

Stack Overflow用户

发布于 2015-06-16 14:47:43

不这是不可能的。如果对象不是lambda,而是带有重载的结构呢?或者是一只聚兰花?您不能假设函数对象有一个而且只有一个签名-有很多方法可以获得多个签名。

下面是一个简单的例子:

代码语言:javascript
复制
struct fun {
    int i;
    void operator()(int x) {}
    void operator()(float x) {} 
};

关于这个结构或它的任何一个论点,没有什么不复杂的或非POD的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30870935

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档