将(某种元)函数应用于

时间:2017-08-20 22:24:34

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

我有一个功能:

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

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

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

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

现在,我想按顺序在包中的每个类型foo<T>或者元组的类型定义中依次调用T

我意识到我可以使用像Boost的MPL或Boost Hana这样的库来获得它,但是我不想把所有这些都放到我的代码中,并且想知道这样做的原则是否可以“捕获”简洁明了。

注意:

  • 如果你能提供一个与普通lambda而不是模板化函数一起使用的答案,那么奖励积分。
  • 答案必须是C ++ 14,而不是C ++ 17。

2 个答案:

答案 0 :(得分:1)

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

因此,如果您可以将工作要求为可变结构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而不是模板化函数一起使用的答案”。

你能举例说明使用吗?

答案 1 :(得分:0)

@ 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计算机上。