方便的 constexpr 函数

Convenient constexpr-function

本文关键字:函数 constexpr 方便      更新时间:2023-10-16

我可以编写一个执行类型推断但不使用传递给它的对象constexpr函数:

template <int N>
struct Foo
{
  static const int value = N;
};
template <typename T>
constexpr int get_value(T const &)
{
  return T::value;
}
void huey()
{
  Foo<3> three;
  static_assert(get_value(three) == 3, ":(");
}

但是,如果要get_value参数是某些其他操作的结果,则此方法将失败:

template <int N>
Foo<N + 1> increase(Foo<N> const &)
{
  return {};
}
void dewey()
{
  Foo<6> six;
  static_assert(get_value(increase(six)) == 7, ":(");
}

编译器(正确地)抱怨increase(six)不是常量表达式。我可以这样解决这个问题:

template <typename T>
constexpr int get_value2()
{
  return T::value;
}
void louie()
{
  Foo<4> four;
  static_assert(get_value2<decltype(increase(four))>() == 5, ":(");
}

但我不喜欢额外的decltype——体操。我可以介绍一个宏:

#define GET_VALUE(x) get_value2<decltype(x)>()

但如果可能的话,我想避免宏。有没有办法允许没有宏的方便语法get_value(some_function(some_object))

increase()也需要constexpr

template <int N>
struct Foo
{
    static const int value = N;
};
template <typename T>
constexpr int get_value(T const &)
{
    return T::value;
}
void huey()
{
    Foo<3> three;
    static_assert(get_value(three) == 3, ":(");
}
template <int N>
constexpr Foo<N + 1> increase(Foo<N> const &)
{
    return {};
}
void dewey()
{
    Foo<6> six;
    static_assert(get_value(increase(six)) == 7, ":(");
}