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++ 指向成员函数默认值的指针出现CRTP相关编译器错误_C++_Templates_Crtp_Pointer To Member - Fatal编程技术网

C++ 指向成员函数默认值的指针出现CRTP相关编译器错误

C++ 指向成员函数默认值的指针出现CRTP相关编译器错误,c++,templates,crtp,pointer-to-member,C++,Templates,Crtp,Pointer To Member,你好 在制作一个基于CRTP的通用包装器来调用任意库函数时,我遇到了一个难以理解的问题。下面是一个非常简单的代码来说明这个问题: #包括 模板 类数据库 { 私人: typedef TBase TSelf; typedef PDerived t派生; 受保护的: typedef PValue TValue_2;; 受保护的: t基地(无效) { std::cout; 私人: typedef TBaseTBase; typedef t导出的TSelf; 公众: t导出(无效): t基地() { s

你好

在制作一个基于CRTP的通用包装器来调用任意库函数时,我遇到了一个难以理解的问题。下面是一个非常简单的代码来说明这个问题:

#包括
模板
类数据库
{
私人:
typedef TBase TSelf;
typedef PDerived t派生;
受保护的:
typedef PValue TValue_2;;
受保护的:
t基地(无效)
{
std::cout;
私人:
typedef TBaseTBase;
typedef t导出的TSelf;
公众:
t导出(无效):
t基地()
{
std::cout());
返回(0);
}
一切都按照预期进行编译和工作。但是,如果我尝试使用指向
TDerived::Foo()
的指针作为
TBase::Call(…)
中第二个参数的默认参数:

静态void调用(PType/*pSomething*/,void(TDerived_u::*pFunction)(void)=&TDerived_uU::Foo,TDerived_UpDerived=TDerived_Uf())
编译器给出了一个语法错误…我感觉它与编译器如何解析代码有关,它无法找出指向尚未定义(或实例化)类的函数的指针。但是,它可以调用
TDerived
构造函数作为
TBase::Call(…)的第三个参数的默认参数
。有人能给我一个明确的答案吗?为什么不接受派生类MFP,而接受派生类的对象作为默认参数

谢谢

编辑:编译器错误(MSVS2010命令行编译器):

FMain.cpp(224):错误C2061:语法错误:标识符'TDerived_uu';FMain.cpp(233):请参阅正在编译的类模板实例化'TBase with[PValue=int,PDerived=TDerived];FMain.cpp(323):请参阅正在编译的类模板实例化'TDerived with[PValue=int]'
这是一个语法错误-它无法识别MFP的默认参数中的类型为
t派生\
。这之后还有其他错误,它们都是语法错误,因为函数定义现在格式不正确。这就是我对它的理解

编辑:基本上,我不明白为什么我可以使用
t派生的对象作为默认参数,但不能使用指向成员函数的指针作为默认参数

编辑:好吧,这让我快发疯了。 首先,我改为
typedef TBaseTBase;
,正如前面所指出的(谢谢大家!)。事实上,它只在MSVC++下编译,因为这个编译器不进行两部分解析;例如,在codepad.org上(使用g++4.1.2),它没有编译。
其次,在那之后,我尝试在codepad.org上使用
静态void调用(PType/*pSomething*/,void(TDerived\uuU:*pFunction)(void)=&TDerived\uUfoo,TDerived\uUpDerived=TDerived\uUfoo())
,它编译并正确运行了!所以我现在真的很困惑:人们向我解释了为什么它不正确(我不明白“为什么”(见我之前的编辑)现在发现g++编译正确了…这是否意味着这只是MSVC++的问题而不是代码?或者代码确实有问题,从标准的角度来看(我看不到),g++“错误地”接受了它(我想不太可能)?…帮助?!导出的
t中的
t值
参数对
t基础
的typedef中类型的作用域似乎是错误的(!)

你有:

 private:
  typedef TBase< TValue_, TDerived > TBase_;
private:
typedef TBaseTBase;
我认为你需要:

 private:
  typedef TBase< typename TBase< PValue, TDerived< PValue > >::TValue_, TDerived > TBase_;
private:
typedef TBase>::TValue,TDerived>TBase;
甚至只是:

 private:
  typedef TBase< PValue, TDerived > TBase_;
private:
typedef TBaseTBase;

< > >强>编辑< /强>:C++标准部分(3): 在类或类模板的定义中,如果是基类 根据模板参数,不检查基类范围 在非限定名称查找期间,在 类模板或成员,或在类的实例化过程中 模板或成员


t导出的
中的
t值
参数对
t基础
的typedef中的类型的作用域似乎是错误的(!)

你有:

 private:
  typedef TBase< TValue_, TDerived > TBase_;
private:
typedef TBaseTBase;
我认为你需要:

 private:
  typedef TBase< typename TBase< PValue, TDerived< PValue > >::TValue_, TDerived > TBase_;
private:
typedef TBase>::TValue,TDerived>TBase;
甚至只是:

 private:
  typedef TBase< PValue, TDerived > TBase_;
private:
typedef TBaseTBase;

< > >强>编辑< /强>:C++标准部分(3): 在类或类模板的定义中,如果是基类 根据模板参数,不检查基类范围 在非限定名称查找期间,在 类模板或成员,或在类的实例化过程中 模板或成员


简单:实例化
TBase
模板类定义时,
调用
函数模板的声明被实例化:

  template< typename PType >
  static void Call( PType , void(TDerived_::*pFunction)() = &TSelf_::Foo, TDerived_ pDerived = TDerived_() )
TBase
模板类定义实例化期间未声明
TDerived\uuuuo::Foo()


顺便说一句,您不需要将参数列表指定为
(void)
()
具有相同的效果,并且不太冗长。

简单:当实例化
TBase
模板类定义时,
调用
函数模板的声明被实例化:

  template< typename PType >
  static void Call( PType , void(TDerived_::*pFunction)() = &TSelf_::Foo, TDerived_ pDerived = TDerived_() )
TBase
模板类定义实例化期间未声明
TDerived\uuuuo::Foo()

顺便说一句,您不需要将参数列表指定为
(void)
()
具有相同的效果,并且是l