【问题标题】:Is it possible to call a member function for every type in a tuple?是否可以为元组中的每种类型调用成员函数?
【发布时间】:2017-09-01 18:10:03
【问题描述】:
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。传递&amp;A::foo print's A's foo。要求是在元组中为 A 的对象打印 A'foo,在元组中为 B 的对象打印 B 的 foo,在元组中为 C 的对象打印 C 的 foo。

Demo

【问题讨论】:

  • 我不知道你在问什么。 没有描述您输入的内容的真正需要的功能的“类似”不是很清楚。你想要什么“喜欢”,你需要什么,等等?您希望f 介于tuple_typeargs... 之间吗?您想完全使用该语法,其中f 恰好是公共成员函数的名称?你想要那个标点符号?
  • 想想如何调用你的函数...ForEach(myTuple, &amp;C::foo)...
  • f(std::get&lt;I&gt;(t), args...); 更改为 std::get&lt;I&gt;(t).f(args...) 并查看 Jarod 的评论。
  • 已提供 Wandbox 链接。传递 &C::foo 是不可行的。什么是C? C 是元组的一种类型。调用 ForEach 时不知道。只有 foo 是已知的,或者更确切地说是 foo 这个名字。

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


【解决方案1】:

std::for_each 的美妙之处在于它将函数应用(在范围的元素上)与迭代(范围的)分离。因此,不会将调用的参数传递给std::for_each(除了已经通过范围传递的被调用者本身)。考虑到这一点,您可能需要考虑使用更接近std 的不同版本的for_each。例如检查这个:iterate over tuple

如果您想进行概括,您可能需要使用Jonathan Müller's tuple_iterator。这使得std::tuples 上的应用程序std 算法就像std::tuplestd 容器一样。特别是,您可以使用std::for_each 进行所需的迭代。

【讨论】:

    猜你喜欢
    • 2015-02-04
    • 1970-01-01
    • 2020-05-31
    • 1970-01-01
    • 1970-01-01
    • 2016-07-03
    • 2021-10-27
    • 2013-01-24
    • 1970-01-01
    相关资源
    最近更新 更多