1

在现代 c++ 中使用 constexpr 修饰符面临典型的新手问题。

我是对的,即使在 c++17 中也无法编写这样的代码(原因http://www.boost.org/doc/libs/1_63_0/libs/hana/doc/html/index.html#tutorial-附录-constexpr)?

并且必须使用“值作为类型”习语(在本例中为打开和关闭文件使用不同的类型)?

#include <boost/hana/filter.hpp>
#include <boost/hana/tuple.hpp>

namespace hana = boost::hana;

enum class State {
  Open, Closed
};

struct File {
  constexpr File(State state) : state_(state) {}

  constexpr State state() const { return state_; }

  const State state_;
};

constexpr auto files = hana::make_tuple(File(State::Closed), File(State::Open));
constexpr auto filtered = hana::filter(files, [](const auto& file) {
  return file.state() == State::Open;
});

int main() {
  return 0;
}
4

2 回答 2

3

您需要将 编码StateFile's 类型的一部分:

template <State TState>
struct File 
{
    constexpr State state() const { return TState; }
};

然后,您需要从过滤函数返回一个编译时友好的布尔值:

constexpr auto files = hana::make_tuple(File<State::Closed>{}, File<State::Open>{});
constexpr auto filtered = hana::filter(files, [](const auto& file) 
{
    return hana::bool_c<decltype(file){}.state() == State::Open>;
});

wandbox 上的实时示例

于 2017-07-10T15:19:05.187 回答
1

在您传递给 的 lambda 中hana::filter,您有两个问题:

  1. file参数不是constexpr
  2. 返回值不是编译时IntegralConstant可转换boolhana::filter.

在任何上下文中保持元组元素 constexpr 的一种方法是将它们包装在 constexpr lambdas(在 C++17 中添加)。

以下代码解决了这两个问题:

constexpr auto files = hana::make_tuple(
  []{ return File(State::Closed); }
, []{ return File(State::Open); }
);

constexpr auto filtered = hana::filter(files, [](auto file) {
  return hana::bool_c<file().state() == State::Open>;
});
于 2017-07-15T23:28:39.677 回答