![](/img/trans.png)
[英]c++ template: How to dynamically choose between classes and primitive types
[英]How do I get this template class to compile for Classes and primitive types?
如何编译以下代码?
我意识到编译器对V<double>
不满意,因为它试图为GetterFn
编译我的typedef,但我希望GetterFn
和GetCalc()
可用于类,但忽略了原始类型。
我该如何重新编写这门课程?
#include <vector>
using namespace std;
class Bar
{
public:
float getMyFloat() const { return 42.5; }
};
template< typename T >
class V
{
public:
typedef float (T::*GetterFn)() const;
void getCalc( std::vector<double>& vec, GetterFn fn ) const
{
vec.clear();
for ( size_t i=0; i<m_v.size(); ++i )
vec.push_back( m_v[ i ].*(fn)() );
}
private:
vector<T> m_v;
};
int main(int argc, char** argv)
{
V<Bar> vb; // ok
V<double> vd; // compiler not happy
}
阿尔夫略带讽刺的回答确实是最简单的方法。 不要让GetterFn
成为成员函数指针,只需使用重载的自由函数来获取值:
void getCalc( std::vector<double>& vec) const
{
vec.clear();
for ( size_t i=0; i<m_v.size(); ++i )
vec.push_back( get_value(m_v[ i ]) );
}
然后恰当地重载get_value
:
double get_value(double value) { return value; }
double get_value(Bar value) { return value.getMyFloat(); }
当然,强烈建议使用比get_value
更具描述性的名称。
double
精灵不能有会员功能。 因此,使用非成员函数。
如果不知道你想要为基本类型做什么,建议完整的解决方案有点困难。 但是,我建议您使用std::is_fundamental
类型特征。
如果您希望整个成员函数集合仅有条件地存在,那么将它们包装到成员助手类中是一个想法:
#include <vector>
#include <type_traits>
#include <cstddef>
class Bar
{
public:
float getMyFloat() const { return 42.5; }
};
template< typename T >
class V
{
private:
static const bool m_primitive = std::is_fundamental<T>::value; // convenience
template <bool B, typename U> struct Helper;
template <typename U> struct Helper<false, U>
{
typedef float (T::*GetterFnType)() const;
void getCalc(std::vector<double> & v1, std::vector<U> const & v2, GetterFnType f)
{
v1.clear();
for (std::size_t i = 0; i < v2.size(); ++i)
v1.push_back((v2[i].*f)());
}
};
public:
// use Helper<m_primitive, T>::GetterFn and Helper<m_primitive, T>::getCalc() here
private:
std::vector<T> m_v;
};
int main(int argc, char** argv)
{
V<Bar> vb; // ok
V<double> vd; // compiler also happy
}
您可能还需要在实际实现中执行一些std::enable_if
。 如果您发布更多详细信息,我们可以详细说明。
如果你对更广泛的重新设计持开放态度,康拉德的回答感觉最终结果会更清晰,更简单,但我再次赞成复杂的模板伏都教:-)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.