为什么 boost::hana 的集合不能默认构造?

Why is boost::hana's set not default constructable?

今天我发现 boost::hanamapset 不是默认可构建的,而 tuple 是。有没有什么特别的原因,因为它很烦人。

这个

#include <boost/hana/set.hpp> 
//                   ^^^ or map

constexpr boost::hana::set<> a{};
//                     ^^^ or map

int main(){}

失败并出现以下错误:

main.cpp:3:30: error: no matching constructor for initialization of 'const boost::hana::set<>'
constexpr boost::hana::set<> a{};
                             ^~~
/home/russellg/Documents/boost/hana-0.6.0/include/boost/hana/set.hpp:65:28: note: candidate constructor not viable: requires single argument 'xs', but no arguments were provided
        explicit constexpr set(tuple<Xs...> const& xs)
                           ^
/home/russellg/Documents/boost/hana-0.6.0/include/boost/hana/set.hpp:69:28: note: candidate constructor not viable: requires single argument 'xs', but no arguments were provided
        explicit constexpr set(tuple<Xs...>&& xs)
                           ^
/home/russellg/Documents/boost/hana-0.6.0/include/boost/hana/set.hpp:57:12: note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 0 were
      provided
    struct set
           ^
/home/russellg/Documents/boost/hana-0.6.0/include/boost/hana/set.hpp:57:12: note: candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 0 were
      provided
1 error generated.

即使空映射或集合是完全有效的:

#include <boost/hana/set.hpp>
//                   ^^^ or map

constexpr auto a = boost::hana::make_set();
//                                   ^^^ or map

int main(){}

编译完美。

感谢任何帮助。

编辑:

它是否为空实际上并不重要,默认构造 maps 和 sets 总是 非法。

hana::sethana::map 表示是实现定义的。该文档警告不要直接使用它们,并提到创建它们的规范方法是分别通过 hana::make_sethana::make_mapdocumentation 状态:

The actual representation of a hana::set is implementation-defined. In particular, one should not take for granted the order of the template parameters and the presence of any constructor or assignment operator. The canonical way of creating a hana::set is through hana::make_set.

hana::tuple 是一个更简单的容器,记录了它的表示,并努力保持与 std::tuple 的某种奇偶校验。 hana::basic_tuple documentation 注释:

[...] hana::tuple aims to provide an interface somewhat close to a std::tuple [...]


至于为什么 hana::sethana::map 的表示是实现定义的,请考虑阅读 FAQ,但简而言之:

  • 允许更灵活地实现编译时和运行时优化
  • 知道类型通常不是很有用

有 github issue 考虑为 hana::map 添加默认构造函数。