簡體   English   中英

功能模板重載-部分專業化

[英]Function template overloading - partial specialization

我有兩個遵循類似模式的類:

oo

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

Foo.cpp

#include <Foo.h>

// specializations of getFoo() for each type
template<>
foo1& Foo::getFoo( Param a, Param b, Param c ) {
    return getFoo1( a, b, c );
}

template<>
foo2& Foo::getFoo( Param a, Param b, Param c ) {
    return getFoo2( a, b, c );
}

上面的Foo編譯就好了。 另一方面, Bar具有與上面的Foo類似的結構或樣式; 唯一的區別是它是靜態的getBar1()getBar2()等不只是普通的函數; 它們是功能模板。

Bar.h

// 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... );
}

為什么當我開始添加作為類模板的類類型時為什么? 一切似乎都壞了。 上面的第一個類編譯並返回適當的Foo 但是,在第二個類Bar我不斷收到函數定義與現有聲明不匹配的編譯器錯誤。

這個問題與這里的問題有關: 使用可變參數參數化和/或重載成員函數模板

這個問題專門針對為何一個人編譯而另一個人不編譯的問題。

上面的第一個類編譯並返回適當的Foo

是的,因為

template<>
foo1& Foo::getFoo( Param a, Param b, Param c ) {
    return getFoo1( a, b, c );
}

這是模板方法getFoo()完全專業化

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

FooType類型固定為foo1

您可以對模板功能(或方法)進行完全專業化。

但是,在第二個類Bar我不斷收到函數定義與現有聲明不匹配的編譯器錯誤。

當然。

因為您正在嘗試部分專門化模板方法getBar()

template<typename Type, template<typename> class BarType, class... FuncParams>
static BarType<Type>& getBar( FuncParams... params );

BarType固定到bar1

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

但是您不能部分專門化模板功能/方法。 該語言禁止使用。

如果您想要類似的東西,則必須通過結構(或類)的部分專業化。

-編輯-

OP問

您說過:“您必須經歷struct(或類)的部分專業化。” 好的; 因此,有一個解決方法:您能否提供一個小的基本示例?

有很多方法可以使用結構(類)的部分專業化來繞過函數/方法的非部分專業化限制。

在下面的基本示例中,我提出了帶有模板func()方法的模板foo結構。 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);
 }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM