2013-03-26 117 views
1

我想創建一個類,可以在陣列之間轉換的花車和雙打多態。也就是說,有關實例(由<double><float>參數化),並決定通過一個float*double*在運行時決定的,不是靜態。C++ - 通過模板仿專業成員函數模板不編譯

作爲proposed answer另一個問題,但根據this answer(因爲我知道這是不可能完全專注一類中的成員函數模板),一個純虛基類BaseDest,提供簡單的重載成員函數是子改性分類以定義DestImpl<T>。我使用這個基類來維護一個DestImpl<T>實例的動態集合,變化範圍爲T。該類提供了assign()成員函數的顯式超載;一個用於double *,另一個用於float *。這個想法是,在運行時,BaseDest::assign()通過多態指針或引用被調用,並且這又調用DestImpl<T>中的正確虛擬assign()成員函數。現在

,重要的是,然後在陣列的非指針類型匹配T IN DestImpl<T>,一個fast_copy()函數被調用(可能是一個的memcpy),並且當類型不匹配較慢的靜態鑄產品逐項複製被執行。所以assign()成員函數將其卸載到模板化的函子。這個仿函數有兩個特化 - 一個是仿函數的類型參數匹配DestImpl<T>(因此調用快速拷貝)的類型,另一個捕捉所有其他情況(並調用慢拷貝)。

但是,我不能讓下面的代碼進行編譯。註釋顯示編譯器錯誤和警告的出現位置 - 我懷疑它們是相關的。我不明白爲什麼apply_helper的第二個專業化無法實例化爲apply_helper<double>

class BaseDest { 
public: 
    virtual ~BaseDest() {} 

    virtual void assign(const double * v, size_t cnt) = 0; 
    virtual void assign(const float * v, size_t cnt) = 0; 
}; 

template <typename T> 
class DestImpl : public BaseDest { 
public: 

    void assign(const double * v, size_t cnt) { 
    assign_helper<T>()(v, cnt); 
    } 
    void assign(const float * v, size_t cnt) { 
    assign_helper<T>()(v, cnt); // ERROR: no matching function for call to object of type 'assign_helper<double>' 

    } 
protected: 

    template <typename U> 
    struct assign_helper { 
    void operator()(const U * v, size_t cnt) { 
     for (size_t i = 0; i < cnt; ++i) { 
     //slow_copy(v[i]); 
     } 
    } 
    }; 

    template <typename U> 
    struct assign_helper<T> { // WARNING: Class template partial specialization contains a template parameter that can not be deduced; this partial specialization will never be used 

    void operator()(const T * v, size_t cnt) { 
     //fast_copy(v, cnt); 
    } 
    }; 
}; 

void test() { 
    DestImpl<double> d; // error mentioned above appears when this is present 
} 

編輯:這裏的東西,它似乎工作 - 移動assign_helper結構(現爲一類)從DestImpl<T>類定義的。我不知道這是做正確的方式,但它似乎工作至今:

// slow copy between different types 
template <typename T, typename U> 
class assign_helper { 
public: 
    void operator()(const U *v, size_t cnt) { 
    // slow copy 
    } 
}; 

// fast copy between same types 
template <typename T> 
class assign_helper<T, T> { 
public: 
    void operator()(const T * v, size_t cnt) { 
    // fast copy 
    } 
}; 


class BaseDest { 
public: 
    virtual ~BaseDest() {} 

    virtual void assign(const double * v, size_t cnt) = 0; 
    virtual void assign(const float * v, size_t cnt) = 0; 
}; 

template <typename T> 
class DestImpl : public BaseDest { 
public: 

    virtual void assign(const double * v, size_t cnt) { 
    assign_helper<T, double>()(v, cnt); 
    } 
    virtual void assign(const float * v, size_t cnt) { 
    assign_helper<T, float>()(v, cnt); 
    } 
}; 

回答

0
template <typename U> 
    struct assign_helper<T> { // WARNING: Class template partial specialization contains a template parameter that can not be deduced; this partial specialization will never be used 

以上是你錯誤的原因。警告明確告訴你,這個定義永遠不會被使用。你想要的而不是template < typename U >template <>

+0

謝謝,但這是原來的問題 - 使用錯誤'模板<>'的結果,這顯然是違法的「類範圍‘assign_helper’的明確的專業化」。我在這個問題中所做的編輯將這個參數化的函子定義移到了類定義之外,這似乎清除了一些事情,儘管我必須相應地更改模板參數化。 – meowsqueak 2013-03-27 20:08:07

+0

啊,對不起。我們今天都學到一些東西。有關該主題的更多信息:http://stackoverflow.com/questions/6301966/c-nested-template-classes-error-explicit-specialization-in-non-namespace-sco – EHuhtala 2013-03-27 22:49:34