Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 局部变量作为非类型模板参数_C++_Templates_Local_Non Type - Fatal编程技术网

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

C++ 局部变量作为非类型模板参数,c++,templates,local,non-type,C++,Templates,Local,Non Type,我想做如下事情: Example(&Class::MemberFunction, this)); //... template<class T_CLASS> inline static void Example(void (T_CLASS::*MemberFunctionPointer)(), T_CLASS* InstancePointer) { SomeClass<T_CLASS>::Bind<MemberFunctionPointer>(

我想做如下事情:

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);
}
示例(&Class::MemberFunction,this));
//...
模板
内联静态void示例(void(T_类::*MemberFunctionPointer)(),T_类*InstancePointer)
{
绑定(InstancePointer);
}
但我得到了错误:*模板参数“T_MEMBER_FUNCTION”:“MemberFunctionPointer”:局部变量不能用作非类型参数*

这个问题有什么解决办法吗?我想提供一种更简单的方法来调用“Bind”

谢谢,米尔科

//编辑:

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

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);
}
这是未经测试和我的头顶,所以语法可能有点偏离

编辑:下面是一个简单的示例来演示此概念:

#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);
}
#包括
结构foo
{

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

记住:模板是一种类型,类型必须在编译时确定


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

我不太确定您想要实现什么

如果
MemberFunctionPointer
是一个变量,其值在编译时未知,例如,可能取决于某些用户行为,则不能将其用作模板参数

如果另一方面,<代码>成员函数指针实际上可以在编译时导出,则应该将其作为模板参数传递,而不是函数参数。请考虑下面的例子:

(在第一种情况下使用
Bind
call
;在第二种情况下,使用
StaticBind
callStatic

#包括
X类{
公众:
int x;
void foo(){printf(“foo\n”);}
void bar(){printf(“bar\n”);}
};
模板
上课{
公众:
静态void绑定(void(T::*MemberFunctionPointer)(),T*obj){
(obj->*成员函数指针)();
}
模板
静态无效静态绑定(T*obj){
(obj->*成员函数指针)();
}
};
模板
静态内联void调用(void(C::*MemberFunctionPointer)(),C*obj){
绑定(MemberFunctionPointer,obj);
}
模板
静态内联void callStatic(C*obj){
模板静态绑定(obj);
}
int main(){
X obj;
调用(&X::foo,&obj);
callStatic(&obj);
返回0;
}

编译时必须知道模板参数。作为函数参数的指针变量的内容取决于调用此函数的方式。编译时不知道这一点

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

template<class T_CLASS, void(T_CLASS::*MemFunPtr)()>
void Example(T_CLASS* InstancePointer) {...}
模板
无效示例(T_类*InstancePointer){…}

这里,MemFunPtr是一个模板参数,它在编译时是已知的,因此可以作为另一个函数或类模板的模板参数重新使用……< /P>请查看这个非常类似的问题。第一句话表明只有类型可以用作模板参数。这是不正确的。C++的模板系统也不接受。n型参数。但这些参数必须是整型的编译时常量,或者是指向外部链接的对象的指针/引用。@sellibitze,真的吗?我明确表示变量是变量,而不是类型…我想我会更明确一点…感谢您的回复。如上所述,我想要我的成员函数pointer是一个非类型模板参数。当像我调用“Bind”一样传递它时,没有问题-但我希望有一个更易于使用的包装函数“Example”,它不接受模板参数。Example应该将MemberFunctionPointer作为参数传递给“Bind”作为非类型模板参数。它总是指向同一个函数,我想让编译器在编译时知道它。这可能吗?@Micro,这就是我的示例所做的,当调用

exec
时,我没有显式指定类型,编译器根据参数进行计算。在您的代码中,您不需要
Bind
,编译器可以根据传入的参数(
fPtr
)计算出来@尼姆,如果我错了,请纠正我,但在你的代码执行中,我不能使用ptr作为非类型模板参数,这正是我要为Bind调用所做的。我不想传递函数指针的类型,而是传递函数指针本身作为参数。我想在编译时对其进行推导,但我不知道如何进行。因此,第二种情况更适合r、 …只有我尝试提供一个方法“调用”这不需要任何模板参数。在这种情况下,您实际上可以使用第一个方法,再加上内联所有函数。但是,如示例所示,绑定函数必须按参数而不是按模板参数获取成员函数指针。启用优化后,它应该归结为一个常量,您不应该遇到任何问题运行时开销。函数
调用的模板
参数实际上可以从传递的参数中推断出来,因此您可以在调用中跳过它。为了清晰起见,我在那里给出了它。谢谢,这就是我想做的。据我所知,确实有
#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;
}
template<class T_CLASS, void(T_CLASS::*MemFunPtr)()>
void Example(T_CLASS* InstancePointer) {...}