是否可以声明指向未知(编译时)返回类型的函数的指针
Is it possible to declare a pointer to a function with unknown (at compile time) return type
我有一个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 );
在这种情况下,我应该如何声明它?
一个受歧视的工会可以为你做到这一点:
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 );
};
对于判别并集,可以应用C++17中的std::variant
,也可以boost::variant
早期的标准修订版。
或者,如果要完全忽略返回类型,可以将成员转换为std::function<void(double)>
并从类型擦除中受益。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
的行为,就可以结合以上两种方法。
喜欢这个
#include <functional>
#include <iostream>
#include <cassert>
int foo(double d) { return d; }
double bar(double d) { return 2*d; }
struct Result {
union {
int i_res;
double d_res;
};
enum { IS_INT, IS_DOUBLE } u_tag;
Result(Result const&) = default;
Result(int i) : i_res{i}, u_tag{IS_INT} {}
Result(double d) : d_res{d}, u_tag{IS_DOUBLE} {}
Result& operator=(Result const&) = default;
auto& operator=(int i)
{ i_res = i; u_tag = IS_INT; return *this; }
auto& operator=(double d)
{ d_res = d; u_tag = IS_DOUBLE; return *this; }
};
int main() {
std::function<Result(double)> cb;
cb = foo;
auto r = cb(1.0);
assert(r.u_tag == Result::IS_INT);
std::cout << r.i_res << 'n';
cb = bar;
r = cb(2.0);
assert(r.u_tag == Result::IS_DOUBLE);
std::cout << r.d_res << 'n';
return 0;
}
如果您的类没有模板,如您的示例所示,您可以执行以下操作:
template <class T>
struct myStruct
{
static T (*ptrToFunction)(double);
};
看起来您正在使用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;
因此,该函数需要使用已知的返回类型进行实例化,然后将其与一些标记的联合一起使用以获得正确的函数调用。
int A::doCall( double value ) {
if( mFunction.rt == rtInt ) {
int result = mFunction.mIntFunction( value );
} else if( mFunction.rt == rtDouble ) {
double result = mFunction.mDoubleFunction( value );
}
}
相关文章:
- 如何获取std::result_of函数的返回类型
- 奇怪的结构&GCC&clang(void*返回类型)
- 如何建立使用模板函数的lambda函数的尾部返回类型
- 为什么与常规GCC不同,即使有"学究性错误",MinGW-GCC也能容忍丢失的返回类型
- 在没有定义返回类型的函数中返回布尔值,并将结果保存在无错误的char编译中-为什么
- C++:返回类型为 T 的模板函数不带 T 类型参数,将无法编译
- C 函数在编译时间返回类型
- 没有返回类型的静态函数可以通过Windows上的编译,但不能传递Linux上的编译
- 如何在编译时决定'auto'返回类型?
- 是否可以声明指向未知(编译时)返回类型的函数的指针
- Clang无法在模板类专业化中编译模板功能,该模板类专业化与模板声明具有 *不同的返回类型 *
- 构造函数没有返回类型,但为什么此部分可以正常编译
- 返回仅移动类型编译,即使复制构造函数不可用
- 如何有条件地编译返回类型的模板化函数
- 在模板函数返回类型上使用std::enable_if来利用SFINAE编译错误
- 为什么编译没有错误?(返回不对所述返回类型进行子类化的类型)
- 为什么VC++2013拒绝编译嵌套类型,当用作模板函数返回类型时,用using关键字使其可见
- 如何在编译时确定此返回类型
- 为什么不在尾部返回类型中使用此运算符进行编译
- C++编译错误,构造函数没有返回类型...但我没有指定一个