是否可以为元组中的每个类型调用成员函数?

时间:2017-04-06 15:41:24

标签: c++ c++11 templates tuples sfinae

namespace details {
template <std::size_t I = 0, typename Tuple, typename Function, typename... Args>
typename std::enable_if<I == std::tuple_size<Tuple>::value, void>::type ForEach(Tuple &t, Function f, Args &... args) {}

template <std::size_t I = 0, typename Tuple, typename Function, typename... Args>
typename std::enable_if<(I < std::tuple_size<Tuple>::value), void>::type ForEach(Tuple &t, Function f, Args &... args) {
    f(std::get<I>(t), args...);
    ForEach<I + 1>(t, f, args...);
}
}

上面是所有类型元组的ForEach功能的实现。它会调用f(tuple_type, args...)

但是我想要tuple_type.f(args...)之类的东西,其中f和args是模板参数。

f将是元组中所有类型的成员函数,将args作为参数。

template <typename... Types>
class TupleManager {
    std::tuple<Types...> t;
    template <typename Function, typename... Args>
    void ForEach(Function f, Args& ... args) {
         details::ForEach<>(t, f, args...);
    }
}

澄清:f需要是一个成员函数,即一个对元组中所有类型都采用相同名称的函数。

例如:

struct A {
    void foo() {
        std::cout << "A's foo\n";
    }
};
struct B : A {
    void foo() {
        std::cout << "B's foo\n";
    }
};

struct C : A {
    void foo() {
        std::cout << "C's foo\n";
    }
};

但现在我无法通过foo。通过&A::foo打印的A&#39; foo。要求是在元组中为A的对象打印A&f; foo,在元组中为B的对象打印B的foo,为元组中的C对象打印C&f; foo。

Demo

1 个答案:

答案 0 :(得分:0)

std::for_each的优点在于(在范围的元素上)函数应用与(范围的)迭代无关。因此,不会将调用的参数传递给std::for_each(被调用者本身已经通过范围传递了)。考虑到这一点,您可能要考虑使用更接近for_each的另一版本std。例如,检查以下一项:iterate over tuple

如果您可以一概而论,则可能要使用Jonathan Müller's tuple_iterator。这样就可以在std上启用应用std::tuple算法,就像std::tuplestd容器一样。特别是,您可以使用std::for_each进行所需的迭代。