Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/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++_C++11_Templates_Variadic Templates_Partial Specialization - Fatal编程技术网

C++ 函数模板重载-部分专门化

C++ 函数模板重载-部分专门化,c++,c++11,templates,variadic-templates,partial-specialization,C++,C++11,Templates,Variadic Templates,Partial Specialization,我有两门课遵循类似的模式: Foo.h // header guard here class Foo { public: Foo() = delete; static foo1& getFoo1( Param a, Param b, Param c ) { // code... } static foo2& getFoo2( Param a, Param b, Param c ) { // code...

我有两门课遵循类似的模式:

Foo.h

// header guard here 

class Foo {
public:
    Foo() = delete;

    static foo1& getFoo1( Param a, Param b, Param c ) {
        // code...
    }

    static foo2& getFoo2( Param a, Param b, Param c ) {
        // code...
    }

    // generic function to return appropriate Foo Type based on template argument 
    template<class FooType>
    static FooType& getFoo( Param a, Param b, Param c );
};

#endif
// header guard

class Bar {
public:
    Bar() = delete;

    template<class IntType = int>
    static bar1<IntType>& getBar1( IntType a, IntType b ) {
        // code...
    }

    template<class RealType = double>
    static bar2<RealType>& getBar2( RealType a, RealType b ) {
        // code...
    }

    template<class IntType = int>
    static bar3<IntType>& getBar3( IntType a ) {
        // code...
    }

    template<class RealType = double>
    static bar4<RealType>& getBar4( RealType a ) {
        // code...
    }

    // ...

    template<class RealType = double>
    static bar12<RealType>& getBar12() {
        // code...
    }

    template<class RealType = double, class A, class B>
    static bar12&<RealType>& getBar12( A a1, A a2, B b1 ) {
        // code...
    }

    template<class RealType = double, class X>
    static bar12&<RealType>& getBar12( std::initialize_list<double> list, X x ) {
        // code...
    }

    template<class RealType = double, class X>
    static bar12&<RealType>& getBar12( std::size_t size, RealType a, RealType b, X x ) {
        // code..
    }

    // Here is where I start to get into problems:
    // I'm trying to do something similar to what I've done above in Foo for a generic function template.
    template<typename Type, template<typename> class BarType, class... FuncParams>
    static BarType<Type>& getBar( FuncParams... params );

}; 

#endif
Bar.cpp

#include "Bar.h"

// specializations of getBar() for each type
template<typename Type, class... FuncParams>
bar1<Type>& Bar::getBar( FuncParams... params ) {
    return getBar1( params... );
}

template<typename Type, class... FuncParms>
bar2<Type>& Bar::getBar( FuncParams... params ) {
    return getBar2( params... );
}
#包括“Bar.h”
//每种类型的getBar()的专门化
模板
bar1&Bar::getBar(FuncParams…params){
返回getBar1(参数…);
}
模板
bar2&Bar::getBar(FuncParams…params){
返回getBar2(参数…);
}
为什么当我开始添加一个类类型,它是一个类模板;一切似乎都破裂了。上面的第一个类编译并返回相应的
Foo
。然而,在第二个类
Bar
中,我不断得到编译器错误,即函数定义与现有声明不匹配

这个问题与此相关:

这个问题是关于为什么一个编译而另一个不编译的

上面的第一个类编译并返回相应的
Foo

template<class FooType>
static FooType& getFoo( Param a, Param b, Param c );
是的,因为

template<>
foo1& Foo::getFoo( Param a, Param b, Param c ) {
    return getFoo1( a, b, c );
}
FooType
类型固定为
foo1

您可以对模板函数(或方法)进行专门化

然而,在第二个类
Bar
中,我不断得到编译器错误,即函数定义与现有声明不匹配

当然

因为您正在尝试对模板方法进行专门化
getBar()

但是您不能局部专门化模板函数/方法。这是语言所禁止的

如果您想要类似的东西,您必须通过结构(或类)的部分专门化

---编辑---

OP提问

你说,“你必须通过结构(或类)的部分专门化。”;所以有一个解决办法:你能提供一个小的基本例子吗

有许多方法可以使用结构(类)的部分专门化来绕过函数/方法的非部分专门化限制

在下面的基本示例中,我提出了一个带有模板
func()
方法的模板
foo
struct。
foo
的单个模板参数是
func()
返回的类型;
func()
的变量模板类型列表是参数类型列表

但是你可以在不同的模式下玩这个游戏

#include <iostream>

template <typename>
struct bar1
 { template <typename ... Args> bar1 (Args && ...) { } };

template <typename>
struct bar2
 { template <typename ... Args> bar2 (Args && ...) { } };

template <typename>
struct foo;

template <typename T>
struct foo<bar1<T>>
 {
   template <typename ... Args>
   static bar1<T> func (Args && ... as)
    { return { std::forward<Args>(as)... }; }
 };

template <typename T>
struct foo<bar2<T>>
 {
   template <typename ... Args>
   static bar2<T> func (Args && ... as)
    { return { std::forward<Args>(as)... }; }
 };

int main()
 {
   foo<bar1<int>>::func(1, "two", 3.0);
   foo<bar2<long>>::func(4.0f, "five", 6L);
 }
#包括
模板
结构条1
{模板bar1(Args&&…{}};
模板
结构条2
{template bar2(Args&&…{}};
模板
结构foo;
模板
结构foo
{
模板
静态bar1函数(参数&&…as)
{return{std::forward(as)…};}
};
模板
结构foo
{
模板
静态bar2函数(参数&&…as)
{return{std::forward(as)…};}
};
int main()
{
foo::func(1,“2”,3.0);
foo::func(4.0f,“五”,6升);
}
上面的第一个类编译并返回相应的
Foo

template<class FooType>
static FooType& getFoo( Param a, Param b, Param c );
是的,因为

template<>
foo1& Foo::getFoo( Param a, Param b, Param c ) {
    return getFoo1( a, b, c );
}
FooType
类型固定为
foo1

您可以对模板函数(或方法)进行专门化

然而,在第二个类
Bar
中,我不断得到编译器错误,即函数定义与现有声明不匹配

当然

因为您正在尝试对模板方法进行专门化
getBar()

但是您不能局部专门化模板函数/方法。这是语言所禁止的

如果您想要类似的东西,您必须通过结构(或类)的部分专门化

---编辑---

OP提问

你说,“你必须通过结构(或类)的部分专门化。”;所以有一个解决办法:你能提供一个小的基本例子吗

有许多方法可以使用结构(类)的部分专门化来绕过函数/方法的非部分专门化限制

在下面的基本示例中,我提出了一个带有模板
func()
方法的模板
foo
struct。
foo
的单个模板参数是
func()
返回的类型;
func()
的变量模板类型列表是参数类型列表

但是你可以在不同的模式下玩这个游戏

#include <iostream>

template <typename>
struct bar1
 { template <typename ... Args> bar1 (Args && ...) { } };

template <typename>
struct bar2
 { template <typename ... Args> bar2 (Args && ...) { } };

template <typename>
struct foo;

template <typename T>
struct foo<bar1<T>>
 {
   template <typename ... Args>
   static bar1<T> func (Args && ... as)
    { return { std::forward<Args>(as)... }; }
 };

template <typename T>
struct foo<bar2<T>>
 {
   template <typename ... Args>
   static bar2<T> func (Args && ... as)
    { return { std::forward<Args>(as)... }; }
 };

int main()
 {
   foo<bar1<int>>::func(1, "two", 3.0);
   foo<bar2<long>>::func(4.0f, "five", 6L);
 }
#包括
模板
结构条1
{模板bar1(Args&&…{}};
模板
结构条2
{template bar2(Args&&…{}};
模板
结构foo;
模板
结构foo
{
模板
静态bar1函数(参数&&…as)
{return{std::forward(as)…};}
};
模板
结构foo
{
模板
静态bar2函数(参数&&…as)
{return{std::forward(as)…};}
};
int main()
{
foo::func(1,“2”,3.0);
foo::func(4.0f,“五”,6升);
}

我认为部分专门化应该写成
Bar::getBar(){…}
。在本例中,编译器只是试图找到一个匹配的声明,但失败了。谢谢您的详细解释。这就是我遇到麻烦的地方;我不知道我是否有不正确的语法或如果它不能做到。你说,“你必须通过结构(或类)的部分专门化。”;所以有一个工作:你能提供一个小的基本例子吗?@ DOTHASTHEEL C++不允许函数的部分专门化。methods@FrancisCugler-用一个小例子改进答案;希望这有帮助。@max66是的。我的意思是,以这种方式编写并不是部分专门化。我认为部分专门化应该写成
Bar::getBar(){…}
。在本例中,编译器只是试图找到一个匹配的声明,但失败了。谢谢您的详细解释。这就是我遇到麻烦的地方;我不知道我是否有不正确的语法或如果它不能做到。你说,“你必须通过