我有一个class A
,其中我想要一个指向函数的指针作为数据成员:
class A
{
protected:
double (*ptrToFunction) ( double );
public:
...
//Setting function according to its name
void SetPtrToFunction( std::string fName );
};
但是,如果我希望ptrToFunction
有时候double
,有时候 - int
会有类似的结果:
//T is a typename
T(*ptrToFunction) ( double );
在这种情况下我该如何宣布?
答案 0 :(得分:25)
discriminated union可以为您做到这一点:
class A
{
template<T>
using cb_type = T(double);
protected:
enum {IS_INT, IS_DOUBLE} cb_tag;
union {
cb_type<int> *ptrToIntFunction;
cb_type<double> *ptrToDoubleFunction;
};
public:
...
// Setting function according to its name
void SetPtrToFunction( std::string fName );
};
对于有区别的联合的更通用和优雅的解决方案可以在{+ 1}}中应用于C ++ 17,或std::variant
用于早期标准修订。
或者,如果要完全忽略返回类型,可以将成员转换为std::function<void(double)>
并从类型擦除中受益。 boost::variant
概念将通过指针将调用转换为Callable
并丢弃返回值,无论它是什么。
static_cast<void>(INVOKE(...))
最后,如果您关注关于返回值但不想存储一个受歧视的联盟。然后了解联盟和#include <functional>
#include <iostream>
int foo(double d) { std::cout << d << '\n'; return 0; }
char bar(double d) { std::cout << 2*d << '\n'; return '0'; }
int main() {
std::function<void(double)> cb;
cb = foo; cb(1.0);
cb = bar; cb(2.0);
return 0;
}
的行为,你可以结合上述两种方法。
std::function
答案 1 :(得分:1)
如果您的课程没有模板,就像您的示例一样,您可以这样做:
console.log(your post url here)
答案 2 :(得分:1)
您看起来正在使用dlsym
/ GetProcAddress
来获取函数地址。
在这种情况下,您需要至少2个呼叫站点来消除呼叫的歧义,因为CPU实际上为每个呼叫执行了不同的操作。
enum ReturnType { rtInt, rtDouble };
void SetPtrToFunction( std::string fName , enum ReturnType typeOfReturn );
struct Function {
enum ReturnType rt;
union {
std::function< int(double) > mIntFunction;
std::function< double(double) > mDoubleFunction;
} u;
} mFunction;
因此需要使用已知的返回类型对函数进行实例化,然后将其与某些标记的union一起使用以获得正确的函数调用。
int A::doCall( double value ) {
if( mFunction.rt == rtInt ) {
int result = mFunction.mIntFunction( value );
} else if( mFunction.rt == rtDouble ) {
double result = mFunction.mDoubleFunction( value );
}
}
答案 3 :(得分:-4)
可以声明一个指向未知(在编译时)返回值
的函数的指针class Myclass
{
template<T1>
protected:
double (*pointertoFunction) ( double );
public:
...
void SetPtrToFunction( std::string firstname );
};
struct myStruct // structure or enum which ever ou want
{
static T1 (*pointertoFunction)(double);
};