C++ 如何在这个特定函数声明中正确使用enable_if?
我有一个类定义为:C++ 如何在这个特定函数声明中正确使用enable_if?,c++,sfinae,enable-if,C++,Sfinae,Enable If,我有一个类定义为: template <typename V, typename E> class AdjacencyList; 对于那些熟悉Dijkstra算法的人来说,只有当E是可添加的非负类型时,才能正确实现。因此,如果E是无符号整数类型,如何正确使用enable\u if构造仅启用此函数 目前,我在这里看到了两个让我感到不舒服的问题: 返回类型和参数都与E有关 E本身不作为类型使用,而是在其他类型模板中使用 由于我对enable\u if构造相对较新,因此我更愿意接受有关该
template <typename V, typename E>
class AdjacencyList;
对于那些熟悉Dijkstra算法的人来说,只有当E
是可添加的非负类型时,才能正确实现。因此,如果E
是无符号整数类型,如何正确使用enable\u if
构造仅启用此函数
目前,我在这里看到了两个让我感到不舒服的问题:
E
有关E
本身不作为类型使用,而是在其他类型模板中使用由于我对
enable\u if
构造相对较新,因此我更愿意接受有关该问题的一些指导,因为这是一个相对非平凡的案例。enable\u if
对于编写具有调整类型要求的多个重载很有帮助。在您的情况下,您没有任何重载,只想强制一些类型限制。因此,您可以使用static\u assert
来检查它们,并为用户提供有意义的诊断消息,而不是通常的模板实例化失败。大概是这样的:
<type_traits>
<utility>
...
static_assert(::std::is_unsigned< E >::value, "edge value type must be unsigned integral type");
static_assert(::std::is_same< E, decltype(::std::declval< E >() + ::std::declval< E >()) >, "edge value type must be addable");
std::map< std::shared_ptr< Vertex<V, E> >, E > dijkstra(
const std::shared_ptr< Vertex<V, E> > &start_vertex) const {
static_assert(
std::is_unsigned<E>::value,
"E must be unsigned.");
}
...
静态断言(::std::is_unsigned::value,“边值类型必须是无符号整数类型”);
静态断言(::std::is_same()+::std::declval())>,“边值类型必须是可添加的”);
仅当E是无符号整数类型时才启用此函数
我按原样收到您的评论/请求,并直接使用
提供的工具如果您想使用
std::enable_If
,可能以下方法对您几乎适用:
std::enable_if_t<std::is_integral<E>::value and std::is_unsigned<E>::value, std::map< std::shared_ptr< Vertex<V, E> >, E >> dijkstra( const std::shared_ptr< Vertex<V, E> > &start_vertex) const;
把它作为你函数的第一行。带有静态断言的错误消息通常对用户更友好。这实际上不是您想要做的 如果
导致模板替换失败,则std::enable_的要点。您希望替换失败的原因是,它不是失败,您可以选择其他重载。然而,这里没有任何意义,因为你不是在尝试选择一个不同的重载,你只是想让它失败
所以,你应该这样做:
<type_traits>
<utility>
...
static_assert(::std::is_unsigned< E >::value, "edge value type must be unsigned integral type");
static_assert(::std::is_same< E, decltype(::std::declval< E >() + ::std::declval< E >()) >, "edge value type must be addable");
std::map< std::shared_ptr< Vertex<V, E> >, E > dijkstra(
const std::shared_ptr< Vertex<V, E> > &start_vertex) const {
static_assert(
std::is_unsigned<E>::value,
"E must be unsigned.");
}
如果你真的想用这种方式编程
C++是这种编程的错误语言,在它运行之前,敲击C++会导致一些非常复杂的C++代码。听起来您实际上想在Agda中编写代码。
谢谢。这有助于我更好地理解SFINAE和SFIAAE。这个问题让我陷入了这样的境地:我试图继承斯威夫特(Swift)和鲁斯特(Rust)等语言中的特征系统。我相信C++会从这样的事情中受益匪浅,虽然实现它的时间已经过去了。@ JaredPayne: StistalyAsStult基本上等同于锈或快速约束。
std::enable_if<std::is_unsigned<E>,
std::map<std::shared_ptr<Vertex<V, E>>, E>::type dijkstra...