如何约束模板参数以符合 std::map 中的键?
我有一个类模板,打算使用其参数 K 作为映射的键。
有没有办法限制模板参数为符合std::map中Key的类型?
我意识到即使没有这样的约束,编译器也会吐出一堆模板错误,例如K 没有运算符 < ()
,但如果我能让我的代码在指定需求时更加明显,那就太好了。
欢迎使用 C++11 解决方案。
template< typename K >
class Foo
{
// lots of other code here...
private:
std::map< K, size_t > m_map;
};
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这取决于您所说的“符合”是什么意思。如果您想验证
K
是否具有<
运算符,那么您可以尝试 Boost 概念检查库。但是,如果您想验证
<
是否在K
上定义了 StrictWeakOrdering,则需要在所有可能的输入下测试运行时行为。It depends on what you mean by "complies." If you want to verify that
K
has a<
operator then you might try the Boost Concept Checking Library.However if you want to verify that
<
defines a StrictWeakOrdering onK
, that would require testing run-time behaviour under all possible inputs.C++11 版本:
输出:
我在这里使用的关键点是表达式 SFINAE:
auto test(K* k) -> decltype(*k < *k)
。如果 Trailing-return-type 中的表达式无效,则test
的这个特定重载将从重载集中删除。换句话说,它是SFINAE'd。§14.8.2 [温度扣除]
您可以在
Foo
类中以三种方式使用它来触发错误。C++11 version:
Output:
The key point I used here is expression SFINAE:
auto test(K* k) -> decltype(*k < *k)
. If the expression in the trailing-return-type is not valid, then this particular overload oftest
is removed from the overload set. In other words, it's SFINAE'd.§14.8.2 [temp.deduct]
You can use it in three flavors for your
Foo
class to trigger an error.完全解决您的问题可能是不可能的。但我可以建议你一个解决方案,如果你想将
K
限制为特定类型,你可以按如下方式定义你的类所以如果
K
是int 你的类按预期工作。否则,您无法构造
Foo
类型的对象。显然你可以完善条件。要检查
K
是否具有operator<
,您可以使用boost::has_less
,但您可以在 文档此特征并不总是能正常工作。A complete solution to your problem probably is impossible. But I can suggest you a solution, if you want to restrict
K
to be a specific type you can define your class as followsSo if
K
isint
your class works as expected. Otherwise you can not costruct object of typeFoo<K>
. Obviously you can refine the condition.To check if
K
has theoperator<
you can useboost::has_less
, but as you can check in the documentation this traits doesn't work properly always.从你的问题来看,我猜你想要一个合适的错误,而不是一大堆错误。
以下代码查找类型是否具有有效的
运算符<
:现在,您可以使用上述构造专门化
class Foo
:只要您使用某种类型< code>A 与
std::map
不兼容,编译器会报错:演示
From your question, I guess you want one suitable error instead of loads of errors.
Following code finds, if a type has a valid
operator <
or not:Now, you can specialize
class Foo
using the above construct:As soon as you use some type
A
which doesn't have compatibility withstd::map
, the compiler will complain with single error:Demo