Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/150.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在这个特定函数声明中正确使用enable_if?_C++_Sfinae_Enable If - Fatal编程技术网

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...