2017-10-11 71 views
1

我有一個模板SoundRecording.h如何在使用C++模板創建的類之間進行轉換?

template <typename T> 
class SoundRecording { 
public: 
    explicit SoundRecording(T init); 
private: 
    T data; 
}; 

template <typename T> 
SoundRecording<T>::SoundRecording(T init){ 
    data = init; 
} 

而且我可以這樣創建這個模板類的實例:

SoundRecording<int16_t> recording(INT16_MAX); 

什麼是recording轉換爲SoundRecording<float>的最佳方式?

我知道我可以用一個簡單的方法,比如我可以聲明:

SoundRecording<float> convertInt16ToFloat(SoundRecording<int16_t> input) 

但我不知道是否有一個更優雅的方式來實現這一目標使用賦值或構造函數運算符。

更新以下評論:我期待定義一個明確的轉換。在上面的例子中,recording.data在施工後等於INT16_MAX。在轉換爲float後,它應該等於1.0F

+0

目前尚不清楚要使用哪種轉換。如果'T'可以轉換爲'U',你是否想要'SoundRecording '可以轉換爲'SoundRecording '?你需要顯式還是隱式轉換,並且只有當'T'可以隱式轉換爲'U'時它才能工作? – Justin

+1

取決於你所說的「優雅」。你描述的工作方式;你究竟想要改進什麼? – anatolyg

+0

對我來說,轉換看起來應該是'SoundRecording'對象的責任,而不是單獨的靜態方法。如果我能避免它們,那麼不是「實用」方法的粉絲。 – donturner

回答

4

你可以有一個模板轉換操作符像

template<class U> 
explicit operator SoundRecording<U>() { /*do the conversion here*/ } 

最少的代碼片段,體現了該技術:

template<class T> 
struct X 
{ 
    template<class U> 
    explicit operator X<U>() {return {};} 
}; 

int main() 
{ 
    X<int> x; 
    auto y = static_cast<X<float>>(x); // conversion 
} 

Live on Coliru

由於@Mooing鴨評論說,試圖請將您的轉換運算符標記爲explicit以避免令人討厭的不需要的編譯器觸發的轉換。

你可以走得更遠一點,使您的轉換隻在T可轉換爲U或反之亦然,通過的std::enable_ifstd::is_convertible組合,像這樣:

template<class U, 
     typename std::enable_if<std::is_convertible<T, U>::value>::type* = nullptr> 
explicit operator X<U>() {return {};} 
+1

喜歡'顯式運算符S ...()' –

+0

爲什麼不將轉換作爲構造函數而不是轉換運算符? – Justin

+0

@Justin你也可以這樣做,但是如果你願意的話,這可以在*施工之後進行轉換*。 – vsoftco

2

爲了讓這個示例用複製構造函數代替鑄造操作符:

#include <cstdint> 

template <typename T> 
class SoundRecording { 
public: 
    SoundRecording(); 

    template <typename U> 
    SoundRecording(const SoundRecording<U>& other); 

private: 
    T *data; 

    template <typename U> 
    friend class SoundRecording; 
}; 

template <typename T> 
SoundRecording<T>::SoundRecording(){ 
    data = new T[10]; 
} 

template <typename T> 
template <typename U> 
SoundRecording<T>::SoundRecording(const SoundRecording<U>& other){ 
    data = new T[10]; 
    for (int i = 0; i < 10; ++i) { 
     data[i] = static_cast<T>(other.data[i]); 
    } 
} 

int main(){ 
    SoundRecording<int16_t> recording16; 
    SoundRecording<float> recordingFloat(recording16); 
} 
相關問題