将constexpr表达式转换为模板非类型参数

时间:2017-11-27 07:51:34

标签: c++ templates variadic-templates constexpr non-type

在以下示例中,我想将一些constexpr值转换为模板非类型参数。 在这里,我有一些constexpra1a2。我可以在那里(也constexpr)使用数据成员d作为模板B的非类型模板参数。

但是,如果我尝试在某个函数transform中进行这种转换,那么这显然已经无效了,因为参数tuple不被认为{{1} }。

constexpr

问题是:我怎样才能进行这种转变。我的想法是编写一个元组#include <cstdint> #include <tuple> template<auto N> struct A { inline static constexpr auto size = N; const uint8_t d[N] {}; }; template<auto N, auto... II> struct B {}; constexpr auto a1 = A<2>{1, 2}; constexpr auto a2 = A<3>{2, 3, 4}; constexpr auto t1 = std::tuple(a1, a2); constexpr auto b1 = B<a1.size, a1.d[0], a1.d[1]>{}; constexpr auto b2 = B<a2.size, a2.d[0], a2.d[1], a2.d[2]>{}; template<typename T> constexpr auto transform(const T& tuple) { constexpr auto x1 = std::get<0>(tuple); // NOK constexpr auto b1 = B<x1.size, x1.d[0], x1.d[1]>{}; // NOK return std::tuple(b1); } constexpr auto t2 = transform(t1); int main() { } 作为参数的元函数。但我无法做到正确......

1 个答案:

答案 0 :(得分:2)

在C ++ 17中,您可以传递constexpr lambda返回您的参数:

constexpr auto t2 = transform([&] { return t1; });

在功能内部你可以&#34;呼叫&#34; lambda并分配给constexpr

template<class Tuple_>
constexpr auto transform(Tuple_ tuple_) {
  constexpr auto tuple = tuple_();
  // ...

一些研究(感谢@wimalopaan)表明这个成语已被描述

http://coliru.stacked-crooked.com/a/073103acf18f80b6

#include <cstdint>
#include <iostream>
#include <tuple>

// not sure how robust this macro is...
#define CONSTEXPR_ARG(arg) [&] { return arg; }

template<auto N>
struct A {
    inline static constexpr auto size = N;
    const uint8_t d[N] {};
};
template<auto N, auto... II>
struct B {};

constexpr auto a1 = A<2>{1, 2};
constexpr auto a2 = A<3>{2, 3, 4};
constexpr auto t1 = std::tuple(a1, a2);

constexpr auto b1 = B<a1.size, a1.d[0], a1.d[1]>{};
constexpr auto b2 = B<a2.size, a2.d[0], a2.d[1], a2.d[2]>{};

template<class Tuple_>
constexpr auto transform(Tuple_ tuple_) {
  constexpr auto tuple = tuple_();
  constexpr auto x1 = std::get<0>(tuple); // NOK
  constexpr auto b1 = B<x1.size, x1.d[0], x1.d[1]>{}; // NOK
  return std::tuple(b1);
}

constexpr auto t2 = transform(CONSTEXPR_ARG(t1));

template<class T>
void inspect(const T& t) {
  std::cout << __PRETTY_FUNCTION__ << std::endl;
}

int main() {
  inspect(t2);
}

输出:

void inspect(const T&) [with T = std::tuple<B<2, 1, 2> >]