Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/apache-kafka/3.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++ 模板专门化与函数重载_C++_Stl_Template Specialization_Standard Library_Overloading - Fatal编程技术网

C++ 模板专门化与函数重载

C++ 模板专门化与函数重载,c++,stl,template-specialization,standard-library,overloading,C++,Stl,Template Specialization,Standard Library,Overloading,我的一本教科书指出,您可以通过模板专门化或函数重载为标准库函数提供自己的实现,如swap(x,y)。这对于任何可以从赋值交换以外的东西中获益的类型都是有用的,比如STL容器(我知道,它已经编写了交换) 我的问题如下: 更好的方法:模板专门化以提供专门的 交换实现,或函数重载提供精确的 您希望在没有模板的情况下使用的参数 为什么更好?或者如果他们是平等的,为什么会这样 短篇故事:可以的时候超负荷,需要的时候专业化 长篇故事:C++对专业化和超载的处理非常不同。最好用一个例子来解释这一点 tem

我的一本教科书指出,您可以通过模板专门化或函数重载为标准库函数提供自己的实现,如
swap(x,y)
。这对于任何可以从赋值交换以外的东西中获益的类型都是有用的,比如STL容器(我知道,它已经编写了交换)

我的问题如下:

  • 更好的方法:模板专门化以提供专门的 交换实现,或函数重载提供精确的 您希望在没有模板的情况下使用的参数

  • 为什么更好?或者如果他们是平等的,为什么会这样


  • 短篇故事:可以的时候超负荷,需要的时候专业化

    长篇故事:C++对专业化和超载的处理非常不同。最好用一个例子来解释这一点

    template <typename T> void foo(T);
    template <typename T> void foo(T*); // overload of foo(T)
    template <>           void foo<int>(int*); // specialisation of foo(T*)
    
    foo(new int); // calls foo<int>(int*);
    
    模板void foo(T);
    模板void foo(T*);//foo(T)过载
    模板void foo(int*);//foo专业化(T*)
    foo(新int);//调用foo(int*);
    
    现在让我们交换最后两个

    template <typename T> void foo(T);
    template <>           void foo<int*>(int*); // specialisation of foo(T)
    template <typename T> void foo(T*); // overload of foo(T)
    
    foo(new int); // calls foo(T*) !!!
    
    模板void foo(T);
    模板void foo(int*);//foo(T)专业化
    模板void foo(T*);//foo(T)过载
    foo(新int);//呼叫foo(T*)!!!
    
    编译器甚至在查看专业化之前都会重载解析。因此,在这两种情况下,重载解析都选择
    foo(T*)
    。然而,只有在第一种情况下,它才能找到
    foo(int*)
    ,因为在第二种情况下
    int*
    专业化是
    foo(T)
    的专业化,而不是
    foo(T*)


    您提到了
    std::swap
    。这使得事情更加复杂

    该标准规定,您可以向
    std
    名称空间添加专门化。很好,所以你有一些
    Foo
    类型,它有一个性能交换,然后你只需要在
    std
    名称空间中专门使用
    swap(Foo&,Foo&)
    。没问题

    但是如果
    Foo
    是一个模板类呢?C++没有函数的部分专门化,所以你不能专门研究<代码>交换< /C>。您唯一的选择是重载,但标准规定不允许将重载添加到
    std
    命名空间中

    此时,您有两个选项:

  • 在您自己的命名空间中创建一个
    swap(Foo&,Foo&)
    函数,并希望通过ADL找到它。我之所以说“希望”,是因为如果标准库调用swap,比如
    std::swap(a,b)那么ADL就根本不起作用了

  • 忽略标准中说不要添加重载的部分,无论如何都要这样做。老实说,尽管技术上不允许这样做,但在所有现实场景中,它都会起作用


  • 但是要记住的一点是,根本不能保证标准库使用
    swap
    。大多数算法都使用
    std::iter\u swap
    ,在我所研究的一些实现中,它并不总是使用
    std::swap
    ,短篇故事:可以过载时,需要时进行专门化

    长篇故事:C++对专业化和超载的处理非常不同。最好用一个例子来解释这一点

    template <typename T> void foo(T);
    template <typename T> void foo(T*); // overload of foo(T)
    template <>           void foo<int>(int*); // specialisation of foo(T*)
    
    foo(new int); // calls foo<int>(int*);
    
    模板void foo(T);
    模板void foo(T*);//foo(T)过载
    模板void foo(int*);//foo专业化(T*)
    foo(新int);//调用foo(int*);
    
    现在让我们交换最后两个

    template <typename T> void foo(T);
    template <>           void foo<int*>(int*); // specialisation of foo(T)
    template <typename T> void foo(T*); // overload of foo(T)
    
    foo(new int); // calls foo(T*) !!!
    
    模板void foo(T);
    模板void foo(int*);//foo(T)专业化
    模板void foo(T*);//foo(T)过载
    foo(新int);//呼叫foo(T*)!!!
    
    编译器甚至在查看专业化之前都会重载解析。因此,在这两种情况下,重载解析都选择
    foo(T*)
    。然而,只有在第一种情况下,它才能找到
    foo(int*)
    ,因为在第二种情况下
    int*
    专业化是
    foo(T)
    的专业化,而不是
    foo(T*)


    您提到了
    std::swap
    。这使得事情更加复杂

    该标准规定,您可以向
    std
    名称空间添加专门化。很好,所以你有一些
    Foo
    类型,它有一个性能交换,然后你只需要在
    std
    名称空间中专门使用
    swap(Foo&,Foo&)
    。没问题

    但是如果
    Foo
    是一个模板类呢?C++没有函数的部分专门化,所以你不能专门研究<代码>交换< /C>。您唯一的选择是重载,但标准规定不允许将重载添加到
    std
    命名空间中

    此时,您有两个选项:

  • 在您自己的命名空间中创建一个
    swap(Foo&,Foo&)
    函数,并希望通过ADL找到它。我之所以说“希望”,是因为如果标准库调用swap,比如
    std::swap(a,b)那么ADL就根本不起作用了

  • 忽略标准中说不要添加重载的部分,无论如何都要这样做。老实说,尽管技术上不允许这样做,但在所有现实场景中,它都会起作用


  • 但是要记住的一点是,根本不能保证标准库使用
    swap
    。大多数算法都使用
    std::iter\u swap
    ,在我所看到的一些实现中,它并不总是转发到
    std::swap
    ,不允许在
    std
    命名空间中重载函数,但允许专门化模板(我记得),所以这是一个选项


    另一个选项是将
    swap
    函数与其操作的对象放在同一名称空间中,并使用std::swap将
    函数放在同一名称空间中

    不允许在
    std
    命名空间中重载函数,但允许专门化模板(我记得),因此这是一个选项

    另一个选项是将您的
    交换
    函数