[英]Passing function as template argument to a member function
我试图将函数作为模板参数传递给类中的函数,但是有一些错误。 代码给出了错误error: missing template arguments before 'obj'
。 我该如何修复它以便编译?
#include<iostream>
double sum_fun(const double &a, const double &b)
{ std::cout<<a+b<<"\n"; }
template <typename F>
class B
{
public:
void fb()(F f1)
{
f1(10.1,10.2);
}
};
int main()
{
B obj(sum_fun); //error
obj.fb(); //error
return 0;
}
对课程的运作方式存在误解。
int main()
{
B obj(sum_fun); // calls B constructor with parameter `sum_fun`
obj.fb(); // calls member function B::fb() with no parameters
return 0;
}
这两行都会引发错误
void fb()(F f1)
是非法语法。 要声明成员函数,只使用一组括号: void fb()
或void fb(F f1)
。 后者在我们的例子中是不正确的,因为你的成员函数调用obj.fb()
没有传递任何参数。 要解决这个问题,请编写一个构造函数,将该函数存储为成员变量,并在函数fb()
使用该变量。
template <typename F>
class B
{
public:
// constructor, initialises member `m_func` through member initialisation
B(F func) : m_func(func) {}
void fb()
{
m_func(10.1,10.2);
}
private:
F m_func;
};
在C ++ 17中,由于自动模板推导,现在不会发出任何错误。 但是在较低的标准(例如C ++ 11)中,缺少模板推导,因此,在声明obj
时需要指定完整的模板类型。
所以在C ++ 17以下的标准中,主要功能应该是:
int main()
{
// C++11: using a function pointer to denote type
B<double(*)(const double&, const double&)> obj(sum_fun);
// ok in C++17, looks cleaner too
// B obj(sum_fun);
obj.fb();
return 0;
}
这里, double(*)(const double&, const double&)
是一个函数指针 ,即一个指向函数的指针 ,该函数返回一个double
并且接受两个参数,类型为const double&
。 函数指针可以被视为一种类型,它满足模板( template<typename F>
)。
就像我们执行std::vector<int>
和std::vector<double>
,我们也可以执行std::vector<double(*)(const double&, const double&)>
来表示返回double
的函数向量。将const double&
作为参数。
顺便说一句, sum_fun
也会引发一个警告:即使返回类型是double
,也不会返回任何内容...更好地指定void
作为返回类型。
是否可以将函数作为参数直接传递给
B::fb()
而不是创建构造函数B::B(F)
并存储在局部变量中?
当然。
#include <iostream>
void sum_fun(const double& a, const double& b)
{
std::cout << a+b << "\n";
}
template <typename F>
class B
{
public:
void fb(F func)
{
func(10.1,10.2);
}
};
int main()
{
B<void(*)(const double&, const double&)> obj;
obj.fb(sum_fun);
return 0;
}
注意,成员函数fb
现在采用单个参数func
,然后我们调用它。 还要注意,在C ++ 17,我们现在不能实例化obj
与B obj;
因为这将是不明确的,并且模板无法自动推断。 相反,我们需要指定完整类型B<void(*)(const double&, const double&)>
。
但是,推荐的替代函数指针的替代方法是使用std::function
,它更通用,并提供更易读的语法。 ( std::function
Demo )
在C ++ 17中,您可以在模板参数列表中使用auto
:
template <auto F>
class B
{
public:
void fb()
{
F(10.1,10.2);
}
};
然后你可以做B<sum_fun>
:
int main()
{
B<sum_fun> obj{};
obj.fb();
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.