【问题标题】:Apply a (sort of a meta) function to a sequence of types将(某种元)函数应用于一系列类型
【发布时间】:2017-08-20 22:24:34
【问题描述】:

我有一个函数:

template <typename T> std::string foo();

您可以将其视为将类型作为输入并生成字符串。

我也有一个参数包,或者一个元组,对你来说更方便;假设是

using std::tuple<MyParameters...> my_types;

现在,我想对包中的每个类型 T 或在元组的类型定义中按顺序调用 foo&lt;T&gt;

我意识到我可能可以使用诸如 Boost 的 MPL 或 Boost Hana 之类的库来实现这一点,但我不想将所有这些都粘贴到我的代码中,并且想知道这样做的原理是否可以“捕获”言简意赅。

注意事项:

  • 如果您能提供一个适用于通用 lambda 而不是模板化函数的答案,则可以加分。
  • 答案必须是 C++14,而不是 C++17。

【问题讨论】:

  • std::string bar[] = {foo&lt;MyParameters&gt;()...};?
  • @T.C.:是的,实际上非常简单。将此发展为下面的答案。

标签: c++ c++14 template-meta-programming map-function


【解决方案1】:

恕我直言,对于这类事情,您需要部分专业化。 所以结构/类,非函数。

因此,如果您可以要求对可变参数结构bar 的方法进行工作,则可以编写foo() 调用bar(例如operator())中的方法,如下所示

template <typename T>
std::string foo ()
 { return bar<T>()(); }

以下是一个完整的工作(我不知道“简洁”是否足够)示例;如果我没记错的话,它是 C++11。

#include <tuple>
#include <complex>
#include <iostream>

template <typename ...>
struct bar;

template <typename T0, typename ... Ts>
struct bar<T0, Ts...>
 {
   std::string operator() ()
    { return "type; " + bar<Ts...>()(); }
 };

template <template <typename ...> class C,
          typename ... Ts1, typename ... Ts2>
struct bar<C<Ts1...>, Ts2...>
 {
   std::string operator() ()
    { return "type container; " + bar<Ts1...>()() + bar<Ts2...>()(); }
 };

template <>
struct bar<>
 { std::string operator() () { return {}; } };

template <typename T>
std::string foo ()
 { return bar<T>()(); }

int main ()
 {
   std::cout << foo<int>() << std::endl;
   std::cout << foo<std::tuple<int, long, short, std::tuple<long, int>>>()
      << std::endl;
   std::cout << foo<std::complex<double>>() << std::endl;
 }

p.s.:我不清楚“使用通用 lambda 而不是模板函数的答案”是什么意思。

你能举个例子吗?

【讨论】:

  • 这似乎有点巴洛克式...您能解释一下您的解决方案相对于@T.C. 的优势,我将其开发为ann answer吗?
  • @einpoklum - 首先,我想我误解了你的问题:我明白你的意图是把某事称为foo&lt;std::tuple&lt;int, long, short, std::tuple&lt;long, int&gt;&gt;&gt;();如果您的意图要求只是另一个使用foo() 的模板(但可变参数)函数...是的,您的解决方案(基于 T.C.)要简单得多。
【解决方案2】:

@T.C. 的评论很到位...

#include <array>
#include <string>
#include <iostream>

template <typename T> std::string foo() { 
    return std::to_string(sizeof(T)); 
}

template <typename... Ts>
std::array<std::string, sizeof...(Ts)> multi_foo() {
    return { foo<Ts>()... };
}

int main() {
    auto size_strings = multi_foo<char, short, int, long, long long>();
    for(const auto& s : size_strings) { std::cout << s << ' '; };
    std::cout << std::endl;
}

另见live version - 产生预期的输出:

1 2 4 8 8

在 x86_64 机器上。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-03
    • 2018-11-10
    • 2019-03-10
    • 1970-01-01
    • 1970-01-01
    • 2016-01-08
    相关资源
    最近更新 更多