局部变量作为非类型模板参数

发布于 2024-11-17 11:07:26 字数 654 浏览 7 评论 0原文

我想做类似以下的事情:

Example(&Class::MemberFunction, this));

//...

template<class T_CLASS>
inline static void Example(void (T_CLASS::*MemberFunctionPointer)(), T_CLASS* InstancePointer)
{
  SomeClass<T_CLASS>::Bind<MemberFunctionPointer>(InstancePointer);
}

但我收到错误: *模板参数 'T_MEMBER_FUNCTION' : 'MemberFunctionPointer' : 局部变量不能用作非类型参数*

此问题有任何解决方案吗?我想提供一种更简单的方法来调用“Bind”,

谢谢,Mirco

//edit:

我希望 MemberFunctionPointer 成为一个非类型模板参数,因为在“Bind”中我再次需要它作为模板参数。 正如您在答案中所写,在我的例子中,MemberFunctionPointer 是一个变量,其值在编译时未知。但 MemberFunctionPointer 总是指向同一个函数。有没有一种方法可以使其恒定,以便编译器在编译时知道它?

I want to do something like the following:

Example(&Class::MemberFunction, this));

//...

template<class T_CLASS>
inline static void Example(void (T_CLASS::*MemberFunctionPointer)(), T_CLASS* InstancePointer)
{
  SomeClass<T_CLASS>::Bind<MemberFunctionPointer>(InstancePointer);
}

But I get the error: *template parameter 'T_MEMBER_FUNCTION' : 'MemberFunctionPointer' : a local variable cannot be used as a non-type argument*

Any solutions for this problem? I want to provide an easier way to call "Bind"

Thanks, Mirco

//edit:

I want MemberFunctionPointer to be a non-type template parameter because in "Bind" I again need it as a template argument.
As you wrote in your answers, in my case MemberFunctionPointer is a variable and its value is unknown at compile time. But MemberFunctionPointer always points to the same function. Is there a way to for example make it constant so that the compiler knows it at compile time?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

高速公鹿 2024-11-24 11:07:26

模板参数可以有两种:类型和编译时常量表达式。函数参数的内容不是编译时可确定的值。因此,编译器无法基于它实例化模板。

请记住:模板是一种类型。并且类型必须在编译时可确定。

您可能应该将成员指针作为参数传递给 Bind 函数。

There are two kinds of things template parameters can be: types and compile-time constant expressions. The contents of a function parameter is not a compile-time determinable value. And therefore, the compiler cannot instantiate a template based on it.

Remember: a template is a type. And types must be determinable at compile time.

You probably should pass the member pointer as an argument to the Bind function.

伤感在游骋 2024-11-24 11:07:26

我不太确定你想达到什么目的?

如果 MemberFunctionPointer 是一个变量,其值在编译时未知,并且例如可能取决于某些用户行为 - 那么它不能用作模板参数。

另一方面,如果可以在编译时实际推导 MemberFunctionPointer,则应将其作为模板参数而不是函数参数传递。考虑以下示例:(

在第一种情况下使用 Bindcall;在第二种情况下,使用 StaticBindcallStatic)

#include <stdio.h>

class X {
  public:
    int x;
    void foo() {printf("foo\n");}
    void bar() {printf("bar\n");}
};

template <typename T>
class SomeClass {
  public:
    static void Bind(void (T::*MemberFunctionPointer)(), T *obj) {
      (obj->*MemberFunctionPointer)();
    }
    template <void (T::*MemberFunctionPointer)()>
    static void StaticBind(T *obj) {
      (obj->*MemberFunctionPointer)();
    }
};

template <class C>
static inline void call(void (C::*MemberFunctionPointer)(), C *obj) {
  SomeClass<C>::Bind(MemberFunctionPointer,obj);
}

template <class C, void (C::*MemberFunctionPointer)()>
static inline void callStatic(C *obj) {
  SomeClass<C>::template StaticBind<MemberFunctionPointer>(obj);
}

int main() {
  X obj;
  call<X>(&X::foo,&obj);
  callStatic<X,&X::bar>(&obj);
  return 0;
}

I am not quite sure what you are trying to achieve?

If a MemberFunctionPointer is a variable, that the value of is unknown at compile time and, for example, may depend on some user behaviour - then it cannot be used as a template argument.

If, on the other hand, MemberFunctionPointer can be actually deduced at compile-time, you should pass it as a template argument, instead of a function parameter. Consider the following example:

(use Bind and call in the first case; in the second case, use StaticBind and callStatic)

#include <stdio.h>

class X {
  public:
    int x;
    void foo() {printf("foo\n");}
    void bar() {printf("bar\n");}
};

template <typename T>
class SomeClass {
  public:
    static void Bind(void (T::*MemberFunctionPointer)(), T *obj) {
      (obj->*MemberFunctionPointer)();
    }
    template <void (T::*MemberFunctionPointer)()>
    static void StaticBind(T *obj) {
      (obj->*MemberFunctionPointer)();
    }
};

template <class C>
static inline void call(void (C::*MemberFunctionPointer)(), C *obj) {
  SomeClass<C>::Bind(MemberFunctionPointer,obj);
}

template <class C, void (C::*MemberFunctionPointer)()>
static inline void callStatic(C *obj) {
  SomeClass<C>::template StaticBind<MemberFunctionPointer>(obj);
}

int main() {
  X obj;
  call<X>(&X::foo,&obj);
  callStatic<X,&X::bar>(&obj);
  return 0;
}
酒儿 2024-11-24 11:07:26

模板参数必须在编译时已知。作为函数参数的指针变量的内容取决于该函数的调用方式。这在编译时是未知的!

如果您在编译时已经知道该指针,则可以将函数指针运行时参数转换为模板参数:

template<class T_CLASS, void(T_CLASS::*MemFunPtr)()>
void Example(T_CLASS* InstancePointer) {...}

这里,MemFunPtr 是一个在编译时已知的模板参数,因此可以重新用作另一个函数的模板参数或类模板...

Template parameters have to be known at compile-time. The contents of a pointer variable that is a function's parameter depends on how this function is invoked. This is not known at compile-time!

If you know this pointer at compile-time already, you can turn the function pointer runtime parameter into a template parameter:

template<class T_CLASS, void(T_CLASS::*MemFunPtr)()>
void Example(T_CLASS* InstancePointer) {...}

Here, MemFunPtr is a template parameter that is known at compile-time and can thus be resused as a template parameter for another function or class template...

中性美 2024-11-24 11:07:26

MemberFunctionPointer 是一个变量,而不是类型(或编译时常量),因此无法使用,您需要的是该函数的真实签名,类似这样的东西可能是更好..

template<typename T_FUNC_PTR, class T_CLASS>
inline static void Example(T_FUNC_PTR fPtr, T_CLASS* InstancePointer)
{
  SomeClass<T_CLASS>::Bind<T_FUNC_PTR>(fPtr, InstancePointer);
}

即让编译器推断出函数指针的类型(注意:您也必须将指针传播到函数),以调用

Example(&foo::bar, foo_inst);

这是未经测试的并且超出了我的想象,因此语法可能会稍微偏离...

编辑:这里是一个更简单的例子来演示这个概念:

#include <iostream>
struct foo
{
  void bar() { std::cout << "foo::bar()" << std::endl; }
};

template<typename T_FUNC_PTR, typename T_CLASS>
void exec(T_FUNC_PTR ptr, T_CLASS& inst)
{
  (inst.*ptr)();
}

int main(void)
{
  foo inst;
  exec(&foo::bar, inst);
}

MemberFunctionPointer is a variable not a type (or compile-time constant), hence cannot be used, what you need is the real signature of that function, something like this may be better..

template<typename T_FUNC_PTR, class T_CLASS>
inline static void Example(T_FUNC_PTR fPtr, T_CLASS* InstancePointer)
{
  SomeClass<T_CLASS>::Bind<T_FUNC_PTR>(fPtr, InstancePointer);
}

i.e. let the compiler deduce the type of the function pointer (NOTE: you will have to propagate the pointer to the function too), to call

Example(&foo::bar, foo_inst);

This is untested and off the top of my head, so the syntax could be slightly off...

EDIT: here is a simpler example to demonstrate the concept:

#include <iostream>
struct foo
{
  void bar() { std::cout << "foo::bar()" << std::endl; }
};

template<typename T_FUNC_PTR, typename T_CLASS>
void exec(T_FUNC_PTR ptr, T_CLASS& inst)
{
  (inst.*ptr)();
}

int main(void)
{
  foo inst;
  exec(&foo::bar, inst);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文