C ++自动检测模板参数?

问题描述

| 我试图定义一个像任务耕作这样的递归构造。在这里,我正在尝试两个可以嵌套的操作数,这些操作数可以递归地用于任何数量的操作数。
template <typename T1,typename T2>
class Farm
{
  private:
    T1 *task1;
    T2 *task2;
  public:
    // save them so that I can use them when invoking call operator
    Farm(T1 *_t1,T2 *_t2): task1(_t1),task2(_t2) { }

    void operator()()
    {
      // invoke call operator,meaning a farm Could be a task (arbitrary nesting)
      (*task1)();
      (*task2)();
    }
};
int main()
{
    ... create two pointer(A *a,B *b...)
    Farm(a,b); // error: missing template arguments before ‘(’ token

    Farm<A,B>(a,b); // in this works,it works
}
问题在于自动检测模板参数,在这种情况下不起作用。我在做什么错,如何通过gcc编译器实现此模板参数隐式检测。 谢谢!     

解决方法

        类/构造函数不会像函数那样自动检测类型。您需要编写包装函数来创建您的类。 如下所述,并称为对象生成器模式。 (感谢@Itjax!)
template <typename T1,typename T2>
Farm<T1,T2> makeFarm(T1* a,T2* b) {
      return Farm<T1,T2>(a,b);
}

// silly example
Farm<T1,T2> farm = makeFarm(a,b);

// better example
template<typename T>
void plow(T& farm) { farm.applyTractor(...); }

void blah() {
    plow(makeFarm(b,a)) 
}
当使用lambda / bind / foreach和类似的部件时,当您想创建带有某些参数的模板类的临时对象并避免指定其类型时,这种模式会出现很多,通常将其发送到另一个模板函数(
std::for_each
)或多态对象(
std::function
)。 注意:生成器函数通常是内联的,并且通过复制删除优化,您的代码中可能根本不会调用任何复制构造函数。如果无法复制对象,则makeFarm()应该返回一个智能指针(在现代C ++中,preferred4ѭ是首选)。     ,        通常的解决方法是提供一个返回实际实现的模板函数。标准C ++库大量使用了此库,例如与std :: make_pair。 例:
template<typename T>
struct foo_t {
    ...
};

template<typename T>
foo_t<T> foo(T const &f) {
    return foo_t<T>(f);
}
之所以可行,是因为对于函数,编译器可以从参数列表中推断出类型名称。     ,        您可以为Farm类添加一个基类:
class FarmBase
{
  public:
    virtual ~FarmBase(){}

    virtual void operator()() = 0;
};


template <typename T1,typename T2>
class Farm : public FramBase
{
  private:
    T1 *task1;
    T2 *task2;
  public:
    // save them so that I can use them when invoking call operator
    Farm(T1 *_t1,T2 *_t2): task1(_t1),task2(_t2) { }
    virtual ~Farm(){}

    virtual void operator()()
    {
      // invoke call operator,meaning a farm could be a task (arbitrary nesting)
      (*task1)();
      (*task2)();
    }
};
template< typename A,typename B >
FarmBase* Create( A *a,B *b )
{
  return new Farm< A,B >( a,b );
}
那么主看起来像:
int main()
{
    //... create two pointer(A *a,B *b...)

    FarmBase *fobj = CreateFarm( a,b );
}
    

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...