2017-10-11 125 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); 
} 
相关问题