我正在努力将用户定义类型作为hana::map
中的键。 我遇到static_assert
,说比较必须在 编译时间。我确实为constexpr bool operator==
组合了(我相信)他们所有人的组合 。有什么问题?由于我的operator==
是constexpr
,我的对象在编译时应该是可比较的,对吧?使用Boost.Hana定义编译时可比较的对象
2
A
回答
3
您必须从比较运算符中返回integral_constant<bool, ...>
,而不是constexpr bool
。以下作品:
#include <boost/hana.hpp>
#include <cassert>
#include <string>
namespace hana = boost::hana;
template <int i>
struct UserDefined { };
template <int a, int b>
constexpr auto operator==(UserDefined<a>, UserDefined<b>)
{ return hana::bool_c<a == b>; }
template <int a, int b>
constexpr auto operator!=(UserDefined<a>, UserDefined<b>)
{ return hana::bool_c<a != b>; }
int main() {
auto m = hana::make_map(
hana::make_pair(UserDefined<0>{}, std::string{"zero"}),
hana::make_pair(UserDefined<1>{}, 1)
);
assert(m[UserDefined<0>{}] == "zero");
assert(m[UserDefined<1>{}] == 1);
}
为什么?
要理解为什么一个constexpr bool
比较运营商是不够的,考虑伪实施hana::map::operator[]
:
template <typename ...implementation-defined>
struct map {
template <typename Key>
auto operator[](Key const& key) {
// what now?
}
};
内operator[]
,在类型的返回值的取决于密钥。我们必须以某种方式提取表示哪个值与该关键字相关联的bool
,但是必须在编译时知道bool
(即,是常数表达式)以使返回类型依赖于该关键字。因此,在operator[]
内部,我们需要一个constexpr bool
,表示key
是否与地图给定值关联。但是,由于无法指定key
是constexpr
参数的事实,因此即使Key
已定义constexpr bool operator==
,我们也无法从该参数中提取constexpr bool
。换句话说,
template <typename Key>
auto operator[](Key const& key) {
// impossible whatever some_other_key_of_the_map is
constexpr bool found = (key == some_other_key_of_the_map);
// return something whose type depends on whether the key was found
}
只有这样,才能达到上述的是做这样的事情
template <typename Key>
auto operator[](Key const& key) {
constexpr bool found = decltype(key == some_other_key_of_the_map)::value;
// return something whose type depends on whether the key was found
}
,因此需要Key::operator==
返回IntegralConstant
。有关于这个和相关的概念here和here的更多信息。
相关问题
- 1. 比较自定义对象c#
- 2. Java比较自定义对象
- 3. 比较2个自定义对象 - C#
- 4. 自定义对象比较器
- 5. 自定义比较器使用单个对象
- 6. 通用对象比较比较例程
- 7. 比较对象
- 8. 比较对象
- 9. Windows GCC和MSVC编译器之间的编译时间比较
- 10. 对象的比较
- 11. 比较两个用户定义对象的数组
- 12. C++编译时类型比较
- 13. 排序当只有特定对象可比较时才设置
- 14. 值比较应用程序定义的或对象定义的错误
- 15. 使用LINQ比较对象的列表
- 16. 使用IComparable比较对象的问题
- 17. 使用比较器来比较Java中的对象属性
- 18. 在编译时决定构造对象
- 19. 尝试使用String时VB编译错误。比较
- 20. Android Studio 2比较对象和布尔编译成功时,它不应该?
- 21. 比较JNI对象引用
- 22. Powershell比较对象
- 23. 比较NSDate对象
- 24. C#对象比较
- 25. 比较itemgetter对象
- 26. java对象比较
- 27. 在编译时使用较旧的C++实现检查一些编译时定义
- 28. 在对象中使用比较器
- 29. 使用node.js比较两个对象
- 30. java比较对象:使用反射?