通常在元组的每个元素上调用成员函数

时间:2015-02-21 04:28:04

标签: c++ templates c++11 template-meta-programming stdtuple

第一步:展开元组并将元素传递给函数:

我有一个带N个参数的函数

void func(int, double, char);

和具有匹配类型的元组

std::tuple<int, double, char> tuple;

As per this stackoverflow question,我能够扩展元组并调用函数。

第二步:展开元组并将每个元素上调用成员函数的结果传递给函数:

更进一步,我的元组包含多个类模板实例:

template<typename T>
struct Foo;

std::tuple<Foo<int>, Foo<double>, Foo<char>>

Foo有一个成员函数Foo<T>::get(),它返回T类型的值。

As per this stackoverflow answer, 我有以下工作代码,它扩展了元组并在每个元素上调用element.get(),最终将结果传递给func

不幸的是,我已经硬编码element.get()的调用。

第三步:规定在每个元组元素上调用哪个成员函数:

(这就是我正在寻求帮助的地方)

是否有可能使这个通用?也就是说,传递哪个成员函数来调用apply,因此将它作为通用实用程序?

我想也许我可以使用std::mem_fn来包装函数(std::mem_fn(&Foo::get))并将生成的对象传递给apply,但这不起作用,因为{{1} }是一个类模板:

  

Foo

有没有办法让这个通用?

以下工作示例:

error: ‘template<class T> struct Foo’ used without template parameters

1 个答案:

答案 0 :(得分:4)

您不能使用mem_fn创建一个在异构类型的对象上调用成员函数的包装器,因为mem_fn创建的包装器会将指针包装到特定成员的特定成员类型。

诀窍是使用模板化函数调用操作符传递一些东西,该操作符可以接受任何适当的类型并调用成员函数。

在C ++ 14中,传递一个多态lambda:

[](auto&& obj) -> decltype(auto) { return std::forward<decltype(obj)>(obj).get(); }

对于C ++ 11,您需要手动编写等效的仿函数:

struct call_get {
    template<class T>    
    auto operator()(T&& obj) const -> decltype(std::forward<T>(obj).get()) {
         return std::forward<T>(obj).get(); 
    } 
};