我对C ++模板的这个问题感到困惑。
我有一个定义如下的课程:
template <class T>
class DataConsumer
{
public:
DataConsumer() : processCount(0)
{}
~DataConsumer()
{}
// Sub classes override this in order to do their thing
void preConsume()
{
std::cout << "Preconsume called" << std::endl;
processCount++;
}
virtual void consume(const T *dataSource)
{
preConsume();
}
private:
long long processCount; // The bare bones template keeps track of the number of data frames it has consumed
};
DataConsumer模板应该采用DataSource类型。 DataSource本身就是一个复杂的类型;意思是它也用另一个参数模板化:
template <class T>
class DataSource
{
public:
// C-tor and D-tor
DataSource() : currentFrame(new T)
{}
// Note that this is a weak assignment as the data
// is not copied; the pointers are merely set to the
// existing frames properties
DataSource(T& existingFrame) : currentFrame(new T)
{
currentFrame->frame = existingFrame.frame;
currentFrame->meta = existingFrame.meta;
}
~DataSource()
{}
// Update function. Specializations expand on this
void update()
{}
// Return a const pointer to something (the data source can be an image frame, textual, binary etc.)
const T * getCurrentDataFrame() const
{
const T * const frame_ptr = currentFrame.get(); // Just return an unmodifiable pointer
return frame_ptr;
}
void echo()
{
// Generic data source just prints its current frame
std::cout << currentFrame->frame << currentFrame->meta << std::endl;
}
private:
boost::shared_ptr<T> currentFrame; // The actual data frame object
};
我的问题是:我想查询DataConsumer类中的DataSource对象的基础模板参数。例如,这段代码可以正常工作:
virtual void consume(const T *dataSource)
{
preConsume();
std::cout << dataSource->getCurrentDataFrame()->toString() << std::endl; // This WORKS!
}
我真正想要的是获取getCurrentDataFrame()返回的类型:
virtual void consume(const T *dataSource)
{
preConsume();
INSERT_TYPE_HERE * frame = getCurrentDataFrame();
std::cout << frame->toString() << std::endl; // How do I do this?
}
有人可以帮我解释一下所需的语法吗?
答案 0 :(得分:0)
INSERT_TYPE_HERE * frame = getCurrentDataFrame();
也许使用自动?
auto frame = getCurrentDataFrame();
&#34; type_traits&#34;技术基本上具有公共typedef。像这样:
template<typename T>
struct DataFrame { };
template<typename T>
class DataSource
{
public:
typedef DataFrame<T> frame_type;
//using frame_type = DataFrame<T>; // c++11
};
template<typename T>
virtual void consume(const T *dataSource) // imagine T is DataSource
{
preConsume();
T::frame_type * frame = getCurrentDataFrame();
std::cout << frame->toString() << std::endl; // How do I do this?
}
答案 1 :(得分:0)
通常一个人在模板中创建typedef
来为其基础类型和依赖类型别名
template <class T>
class DataSource
{
public:
typedef T value_type;
typedef value_type const * pointer_to_const_type;
// ....
// Return a const pointer to something (the data source can be an image frame, textual, binary etc.)
pointer_to_const_type getCurrentDataFrame() const
// .....
而不是DataConsumer
代码
template <class T>
class DataConsumer
{
public:
typedef T value_type;
virtual void consume(const DataSource<T> *dataSource)
{
preConsume();
typename DataSource<T>::pointer_to_const_type frame = getCurrentDataFrame();
std::cout << frame->toString() << std::endl; // How do I do this?
}
如果您可以使用c ++ 11 standrad,则可以使用auto
关键字代替typename DataSource<T>::pointer_to_const_type
作为@Phantom点。
答案 2 :(得分:0)
使用类型特征:
template <class T> DataSource {
public:
typedef T element_type;
};
template <class T> DataConsumer {
public:
void consume(T *arg) {
typename T::element_type local_var;
...
}
};
使用C ++ 11 decltype:
template <class T> DataSource {
};
template <class T> DataConsumer {
public:
void consume(T *arg) {
decltype(arg->getCurrentDataFrame()) local_var;
...
}
};
使用模板成员函数:
template <class T> DataSource {
};
template <class T> DataConsumer {
public:
template <class X> void consume(DataSource<X> *arg) {
X local_var;
...
}
};
如果您只想捕获函数调用的返回值,也可以使用C ++ 11 auto:
template <class T> DataSource {
};
template <class T> DataConsumer {
public:
void consume(T *arg) {
auto local_var = arg->getCurrentFrame();
...
}
};