将函数指针传递到模板
Pass function pointer to template
我确实遇到过类似的情况:
#include <iostream>
template<class B>
class A
{
public:
A<B>(const B& b) : m_b(b) {}
void foo()
{
m_b(*this);
}
private:
B m_b;
};
class B
{
public:
template<class C>
void operator()(const C& c)
{
std::cout << "Bar!n";
}
};
int main()
{
B b;
A<B> a(b);
a.foo();
return 0;
}
然后我决定使用函数指针而不是函数对象b,也就是说,我想做这样的事情:
#include <iostream>
template<class B>
class A
{
public:
A<B>(const B& b) : m_b(b) {}
void foo()
{
m_b(*this);
}
private:
B m_b;
};
template<class C>
void bar(const C& c)
{
std::cout << "Bar!n";
}
int main()
{
typedef void (*barPointer)(const A<barPointer>& a); // <--
A<barPointer> a(&bar);
a.foo();
return 0;
}
这显然不会编译(注意<--处的循环性)。我的问题是:人们会怎么做?
我认为要问的关键问题是您的barPointer
类型是什么?它是一个逐点函数,但当您试图定义它时,您已经创建了一个无限递归的定义。为了结束递归,你必须考虑这个指针类型的"根"或"基本情况"是什么。由于你知道要传递给函数的A
实例的类型,那么你实际上是在寻找一个"占位符"类型,它可以在没有循环的情况下实例化模板。这可能是一个非常"通用"的函数指针类型,如void(*)(void*)
,也可能是更具体的类型,但在任何一种情况下,我认为它都需要是一个不包括A
定义的函数指针,但可以传递一个A<>
实例作为其参数。最通用的形式是void(*)(void*)
,但为了更大的类型安全性,您也可以定义某种类型的多态基类。
例如,这里有一个最通用的例子:
typedef void (*generic_t)(void*);
template<typename T>
struct A
{
A(const T& t): func_ptr(t) {}
void foo() { func_ptr(this); }
T func_ptr;
};
void func(void* arg)
{
const A<generic_t>* a = reinterpret_cast<const A<generic_t>*>(arg);
}
int main()
{
A<generic_t> a(&func);
a.foo();
return 0;
}
尽管这看起来很危险,但如果考虑到在basePointer
示例中您已经知道要传递给basePointer
函数指针的对象类型,那就不是真的了。如果您想要更多的类型安全性来防止无意的错误,那么您可以始终创建A
继承自的某种类型的抽象基类。我说"抽象基类"是因为这将允许您使用传递给函数的指针,而无需显式转换为它的派生类型。然后,您的"通用占位符"函数ptr类型可能类似于void(*)(const Base&)
,而不是非类型安全的void(*)(void*)
。
相关文章:
- QMetaObject invokeMethod的基于函数指针的语法
- C++-试图将函数指针推回到另一个CPP文件中的矢量时出错
- c++r值引用应用于函数指针
- 模板函数指针和lambda
- 是否可以将llvm::FunctionType转换为C/C++原始函数指针
- 带有类的函数指针
- () 函子后面的括号,而不是函数指针?
- 全局作用域中函数指针的赋值
- 使用"Task"函数指针队列定义作业管理器
- 将成员函数指针作为参数传递给模板方法
- 如何创建对象函数指针C++映射?
- 匹配函数指针作为模板参数?
- 通过函数指针定义类范围之外的方法
- 存储在类中的函数指针
- C++从函数指针数组调用函数
- 将返回值存储在函数指针数组的指针中是如何工作的?
- 整数键映射到头文件中的成员函数指针
- 从类成员函数到类 C 函数指针的转换
- 如何将内联匿名函数分配给C++函数指针
- 将字符缓冲区强制转换为函数指针