非类型模板参数...这是一个模板! (C ++) [英] Non-type template parameter... that's a template! (C++)

查看:143
本文介绍了非类型模板参数...这是一个模板! (C ++)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我基本上想要生成一个通用C函数的包装器,而不必手动指定类型。所以我有一个回调与一个固定的原型,但我需要做一些特殊的代码在包装器基于包装函数的类型...所以基本上我正在考虑在类模板中使用静态方法将我的函数包装到一个合适的接口例如:

I'm basically looking to generate a wrapper for a generic C function without having to manually specify the types. So I have a callback with a fixed prototype but I'm going to need to do some special code in the wrapper based on the type of the wrapped function... So basically I'm thinking about using a static method in a class template to wrap my function to a conforming interface e.g.:

// this is what we want the wrapped function to look like
typedef void (*callback)(int); 
void foobar( float x ); // wrappee

// doesn't compile
template< T (*f)(S) > // non-type template param, it's a function ptr
struct Wrapper
{
  static void wrapped(int x)
  {
     // do a bunch of other stuff here
     f(static_cast<S>(x)); // call wrapped function, ignore result

  }
}

然后我想做一些事情:

AddCallback( Wrapper<foobar>::wrapped );

但是,问题是我不能直接使用S在Wrapper模板中的函数的参数,我必须首先将其列为一个参数:

However, the problem is that I can't just go ahead and use a "S" in the parameter of the function in the Wrapper template, I have to first list it as a parameter:

template< class T, class S, T (*f)(S) >
struct Wrapper
// ...

但这意味着它很多更痛苦的使用( Wrapper< void,float,foobar> :: wrapped ),理想情况下,我想传递函数指针,类型的参数(和返回类型)。要清楚,在包装函数内,我需要引用函数指针的类型(所以我需要一些等效的S或T)。

But this means it's a lot more painful to use (Wrapper<void,float,foobar>::wrapped), ideally I'd like to just pass in the function pointer there and have it work out the types of the parameters (and return types) automatically. To be clear, inside the wrapped function I'm going to need to refer to the types of the function pointer (so I do need some equivalent of S or T).

有没有办法这样做?

推荐答案

你可能希望考虑的一件事是使用LLVM或类似的,蹦床功能。或者这是一个静态解决方案:

One thing you might wish to consider is using LLVM or similar to generate an appropriate trampoline function at runtime. Or here's a static solution:

#include <iostream>

void f(float f) { std::cout << f << std::endl; }

template<typename T, typename S> struct static_function_adapter {
        template<T(*f)(S)> struct adapt_container {
                static void callback(int v) {
                        f(static_cast<S>(v));
                }
        };

        template<T(*f)(S)> adapt_container<f> adapt() const {
                return adapt_container<f>();
        }
};

template<typename T, typename S> struct static_function_adapter<T, S> get_adapter(T (*)(S)) {
        return static_function_adapter<T, S>();
}

#define ADAPTED_FUNCTION(f) (&get_adapter(f).adapt<f>().callback)

int main() {
        void (*adapted)(int) = ADAPTED_FUNCTION(f);
        adapted(42);
        return 0;
}

get_adapter函数允许我们推断参数和返回类型; adapt()然后将其转换为一个类型参数化的实际函数,最后我们得到一个静态函数回调。

The get_adapter function allows us to infer the argument and return type; adapt() then converts this into a type parameterized on the actual function, and finally we get a static function in callback.

这篇关于非类型模板参数...这是一个模板! (C ++)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆