繁体   English   中英

如何让这个模板类编译为类和基元类型?

[英]How do I get this template class to compile for Classes and primitive types?

如何编译以下代码?

我意识到编译器对V<double>不满意,因为它试图为GetterFn编译我的typedef,但我希望GetterFnGetCalc() 可用于类,但忽略了原始类型。

我该如何重新编写这门课程?

#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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM