C++ 具有默认行为的函数指针

C++ 具有默认行为的函数指针,c++,c++11,function-pointers,C++,C++11,Function Pointers,在我的程序中,我有很多指向外部库提供的函数的指针。其中有些返回值,有些则不返回 若外部库并没有提供函数(指针为NULL)和函数应该返回的值,那个么程序应该采用默认值(在编译时已知) 我试图做到的是减少if语句的数量,并在类中使用以下用例包装指针: enum E { e1, e2, e3 }; UserFunction<uint8_t(int, int), 0> callback1 { user_function_ptr }; // Calls and returns value of

在我的程序中,我有很多指向外部库提供的函数的指针。其中有些返回值,有些则不返回

若外部库并没有提供函数(指针为NULL)和函数应该返回的值,那个么程序应该采用默认值(在编译时已知)

我试图做到的是减少
if
语句的数量,并在类中使用以下用例包装指针:

enum E { e1, e2, e3 };
UserFunction<uint8_t(int, int), 0> callback1 { user_function_ptr }; // Calls and returns value of user_function_ptr
UserFunction<uint8_t(), 0> callback2 { nullptr }; // Returns 0
UserFunction<uint8_t(), 1> callback3 { nullptr }; // Returns 1
UserFunction<E(int), e1> callback4 { user_function_ptr2 }; // Returns enum value and takes one integer argument
UserFunction<void(int)> callback5 { user_function_ptr3 }; // No return value, one argument
UserFunction<void()> callback6 { nullptr }; // Should perform noop
但如果可能的话,我宁愿使用

UserF<R(Args...), Default> callback; // preferred
UserF<Default, R(Args...)> callback; // if above is not possible
UserF<void(Args...)> callback; // if no return value
UserF回调;//首选
UserF回调;//如果以上不可能
UserF回调;//如果没有返回值
我宁愿不使用
std::function
,因为我知道我将只处理指向函数的指针,而不处理指向成员函数、functor对象等的指针。也不允许使用boost(允许使用C++11)


总而言之,问题是:如何强制对默认返回值进行类型检查。

如果你能接受一个小宏,你可以这样做:

template <typename sig, typename T, T v >
struct UserF_;

template <class R, typename ... Args, typename T, T v >
struct UserF_< R(Args...), T, v > {
    // ...
};
#define UserF( F, Default ) UserF_< F, decltype( Default ), Default >

UserF(R(Args...), Default) callback; 
模板
结构用户f;
模板
结构UserF_ur{
// ...
};
#定义UserF(F,默认值)UserF_F
UserF(R(Args…,默认值)回调;
如果不首先将泛型模板非类型参数的类型指定为模板类型参数,则不能使用泛型模板非类型参数

template<class Sig>
struct return_type;
template<class Sig>
using return_type_t=typename return_type<Sig>::type;
template<class R,class...Args>
struct return_type<R(Args...)>{
  using type=R;
};

template <class Sign, return_type_t<Sign> Def>
struct UserF;
非整数非指针
R
会出现问题,因为无法将
双精度
传递给
模板。一种方法是将
Def
double
升级为
double const*
,并使其自动取消引用:

template <class R, R const* Def, class... Args>
struct UserF<R(Args...), Def>{
  // body
模板
结构用户{
//身体

并执行类似于
flag\u void
的操作,将
T=double
转换为
T=double const*

不能
Default
在构造函数中而不是在模板参数中?@jarod42可能应该是这样,因为它需要体操才能使其与双返回类型(etc)一起工作@Jarod42默认值可以在构造函数中传递,但我认为我提出的语法更简洁,而且它需要在内存中存储每个函数指针的默认值。
template<class Sig>
struct return_type;
template<class Sig>
using return_type_t=typename return_type<Sig>::type;
template<class R,class...Args>
struct return_type<R(Args...)>{
  using type=R;
};

template <class Sign, return_type_t<Sign> Def>
struct UserF;
struct void_flag{};
template<class T>
using flag_void=
  typename std::conditional<std::is_same<T,void>{},void_flag*,T>::type;

template <class Sign, flag_void<return_type_t<Sign>> Def=nullptr>
struct UserF;

template <class R, R Def, class... Args>
struct UserF<R(Args...), Def>{
  // body

template <class... Args>
struct UserF<void(Args...), 0>{
  // body
template <class R, R const* Def, class... Args>
struct UserF<R(Args...), Def>{
  // body