簡體   English   中英

為模板化類專門化模板化函數

[英]Specialize templated function for templated class

在C ++中,我試圖專門針對本身已模板化的對象使用模板化函數。

這是一個基本示例:test.h:

template <class T>
class myC {
    T x;
};

template <class U>
void f(U y) {
}

template <>
template <class T>
void f<myC<T> >(myC<T> y) {
}

TEST.CPP

#include "test.h"
int main() {
    myC<double> m;
    f(m);
}

GCC 4.6.1給我以下錯誤消息:

In file included from test.cpp:1:0:
test.h:13:25: error: too many template parameter lists in declaration of ‘void f(myC<T>)’
test.h:13:6: error: template-id ‘f<myC<T> >’ for ‘void f(myC<T>)’ does not match any template declaration
test.h:13:25: note: saw 2 ‘template<>’, need 1 for specializing a member function template

這是可能嗎? 還是有另一種方法可以實現相同的目標?

template <>
template <class T>
void f<myC<T> >(myC<T> y) {
}

您試圖在此處執行的操作稱為部分專業化,在功能模板的情況下是不允許的。

功能模板要么完全專用,要么完全不專用。 語言規范不允許功能模板的部分專業化。

因此,您可以按以下方式重載功能模板:

template <class T>
void f(myC<T> y)  //note that it is overload, not specialization
{ 
}

這是允許的,並且比模板的完全專業化更受青睞。

閱讀Herb Sutter的以下文章:

您不能專門使用模板功能; 只有模板類可以專門化。 編輯:Nawaz的答案是正確的:它是部分專業化,不允許模板函數使用,只能用於類。 完全專業化是可能的:

template <class U> void f(U y) {}
template<> void f<double>(double y) {} // specialization for double

請注意,如果可以從上下文推斷出模板參數,則無需顯式指定它:

template<> void f<>(int y) {} // specialization for int

在您的情況下,由於function參數是模板類,因此無法進行完全專業化。 但是,可以像任何其他函數一樣重載模板函數。 在您的情況下,它將是這樣的:

template <class T>
class myC {
    T x;
};

template <class U>
void f(U y) {
}

template <class T>
void f(myC<T> y) {
}

int main() {
    myC<double> m;
    f(m);
    return 0;
}

據我所知,您不能專門化模板函數,只能模板類(或結構)。

但這幾乎不是一個限制:只需使用靜態公共成員函數聲明一個結構並將模板參數分配給該結構即可:

template <class T>
class myC {
    T x;
};

template <class U>
struct Foo
{
    static void f(U y) {
    }
};

template <>
template <class T>
struct Foo<myC<T> >
{
    static void f(myC<T> y) {
    }
};

缺點是類模板不能自動解決模板參數。 但這可以通過功能模板輕松解決,類似於原始模板:

template <class U>
void f(U y) {
    return Foo<U>::f(y);
}

暫無
暫無

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

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