C++ C++;自动检测模板参数?
我试图定义一个递归构造,就像一个任务。在这里,我尝试使用两个操作数,它们可以递归地处理任意数量的操作数,因为它可以嵌套自身C++ C++;自动检测模板参数?,c++,templates,C++,Templates,我试图定义一个递归构造,就像一个任务。在这里,我尝试使用两个操作数,它们可以递归地处理任意数量的操作数,因为它可以嵌套自身 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 *_
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
}
模板
阶级农场
{
私人:
T1*任务1;
T2*2;
公众:
//保存它们,以便在调用call操作符时使用它们
农场(T1*\UT1,T2*\UT2):任务1(\UT1),任务2(\UT2){}
void运算符()()
{
//调用调用运算符,表示场可以是任务(任意嵌套)
(*任务1)();
(*任务2)();
}
};
int main()
{
…创建两个指针(A*A,B*B…)
场(a,b);//错误:在“(”标记之前缺少模板参数
农场(a,b);//在这项工程中,它起作用了
}
问题在于模板参数的自动检测在这种情况下不起作用。我做错了什么,以及如何通过gcc编译器实现模板参数隐式检测
谢谢!在C++17之前,类/构造函数不像函数那样自动检测类型。您需要编写一个包装函数来创建类 这是按如下方式完成的,并称为模式。(谢谢@Itjax!)
模板
农场制作农场(T1*a、T2*b){
回归农场(a、b);
}
//愚蠢的例子
农场=makeFarm(a,b);
//更好的例子
模板
空心犁(T&farm){farm.applyTractor(…);}
废话{
犁(makeFarm(b、a))
}
当使用lambda/bind/foreach和类似部分时,当您想要创建带有一些参数的模板类的临时对象并避免指定其类型时,这种模式会出现很多,通常会将其发送到另一个模板函数(std::for_each
)或多态对象(std::function
)
注意:生成器函数通常是内联的,使用复制省略优化,代码中可能根本不会调用复制构造函数。如果无法复制对象,makeFarm()应该返回智能指针(现代C++中首选
std::unique_ptr
)通常的解决方法是提供一个返回实际实现的模板函数。标准C++库使用这一点,例如用STD::MaMaGION.< /P>
例如:
template<typename T>
struct foo_t {
...
};
template<typename T>
foo_t<T> foo(T const &f) {
return foo_t<T>(f);
}
模板
结构foo\u t{
...
};
模板
富特富(t const&f){
返回foo_t(f);
}
这是因为对于函数,编译器可以从参数列表中推断类型名。您可以为类场添加基类:
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 );
}
没错。这就是所谓的对象生成器习惯用法:非常感谢您的回答!但是您能告诉我如何扩展此服务器场,使其适用于任意模板参数(使用C++0x可变模板和可能的元组)。我读了很多书,并试图这样做,但没有找到解决方案。@user600029:这是一个不同的问题。请搜索(或发布一个新问题)。就我个人而言,我还没有使用c++0x来帮助您解决这个问题,但我确信这里还有很多其他人知道如何正确地完成。在c++0x中,自动会有什么帮助?只是好奇而已。
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 );
}