方便的constexpr功能

时间:2016-07-15 13:17:15

标签: c++ constexpr

我可以编写一个执行类型推导的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))没有宏?

1 个答案:

答案 0 :(得分:1)

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, ":(");
}