C++ 是否可以获得一个模板来使用一个类和该类的成员函数?

C++ 是否可以获得一个模板来使用一个类和该类的成员函数?,c++,c++11,visual-c++,C++,C++11,Visual C++,我试图为使用大小函数和项目索引函数的通用对象的每个函数创建一个。但是我在语法上有点困难 这是我到目前为止得到的(从第128行开始): classbase1 { 受保护的: 向量项; 公众: base1() :项目({1,2,3}) { } int GetCount()常量 { } }; base2类:公共base1 { 公众: base2() :base1() { } int GetItem(int i)常量 { 退货项目[i]; } }; 派生类:publicbase2 { 公众: 派生的()

我试图为使用大小函数和项目索引函数的通用对象的每个函数创建一个
。但是我在语法上有点困难

这是我到目前为止得到的(从第128行开始):

classbase1
{
受保护的:
向量项;
公众:
base1()
:项目({1,2,3})
{
}
int GetCount()常量
{
}
};
base2类:公共base1
{
公众:
base2()
:base1()
{
}
int GetItem(int i)常量
{
退货项目[i];
}
};
派生类:publicbase2
{
公众:
派生的()
:base2()
{
}
};
模板
每个容器的空(容器*容器,大小(容器基数1::*GetSize)()常量,包含(容器基数2::*GetItem)(大小)常量,函数和正文)
{
对于(大小i=0;i*GetSize();++i)
{
主体(容器->*GetItem(i));
}
}
无效fn()
{
导出x;
对于每个(&x,&DEVERTIVE::GetCount,&DEVERTIVE::GetItem,[](int i){
++一,;
});
}
现在,我从VC++2013中得到一个错误,指出:

1>d:\projects\test\test.cpp(169): error C2064: term does not evaluate to a function taking 0 arguments
1>          d:\projects\test\test.cpp(180) : see reference to function template instantiation 'void for_each<derived,base1,base2,int,int,fn::<lambda_862ea397905775f7e094cde6fe9b462c>>(CONTAINER *,SIZE (__thiscall base1::* )(void) const,CONTAINED (__thiscall base2::* )(SIZE) const,FUNC &)' being compiled
1>          with
1>          [
1>              CONTAINER=derived
1>  ,            SIZE=int
1>  ,            CONTAINED=int
1>  ,            FUNC=fn::<lambda_862ea397905775f7e094cde6fe9b462c>
1>          ]
1>d:\projects\test\test.cpp(171): error C2064: term does not evaluate to a function taking 1 arguments
1>d:\projects\test\test.cpp(169):错误C2064:术语不计算为包含0个参数的函数
1> d:\projects\test\test.cpp(180):请参阅正在编译的函数模板实例化“void for_each(CONTAINER*,SIZE(u thiscall base1::*)(void)const,CONTAINED(u thiscall base2::*)(SIZE)const,FUNC&)”
1> 与
1>          [
1> 容器=派生的
1> ,SIZE=int
1> ,CONTAINED=int
1> ,FUNC=fn::
1>          ]
1> d:\projects\test\test.cpp(171):错误C2064:term未对采用1个参数的函数求值

有什么问题吗?

您有两个bug。通过非常量左值引用获取函子-
FUNC&body
,它不绑定到lambda这样的临时函数;这被允许这种绑定的糟糕的MSVC扩展所隐藏。您应该通过值(标准库通常采用的方式)、常量左值引用(如果复制成本高和/或标识重要)或转发引用(如果标识重要且
operator()
可以是非
const
)来接受函数对象

其次是运算符优先级。后缀函数调用运算符的优先级高于
*
->*
container->*GetSize()
container->*(GetSize())
;您需要
(container->*GetSize)(


我也不确定这个设计。提供一个统一的接口,并简单地执行,例如,
container.size()
container.at(i)
可能比使用这个复杂的成员函数指针系统要好。

哦,这不是很好吗但我不是这个图书馆的创造者。
base1
base2
派生的
仅用于此处,不用于实际生产。谢谢。顺便问一下,你指的MSVC扩展是什么?我应该使用
FUNC-body
而不是
FUNC-const&body
?似乎与我制作的另一个使用
FUNC&body
@Adrian MSVC的工具一起工作过,它允许非常量左值引用绑定到临时对象。标准库的样式是按值传递functor,但您也可以使用
const FUNC&
FUNC&&
(转发参考)。啊,很高兴知道。但是,前瞻性参考的意义是什么?当你想同时接受左值和右值,但身份很重要(因此不能复制/按值传递),并且函子的
操作符()
可以是非常量(因此不能按常量引用传递)时,我会移动什么?@Adrian
std::shuffle
就是一个例子——它通过转发引用获取其RNG。在这种情况下,它实际上不用于转发;斯科特·迈尔斯(Scott Meyers)的旧“通用参考”术语可能更合适。
1>d:\projects\test\test.cpp(169): error C2064: term does not evaluate to a function taking 0 arguments
1>          d:\projects\test\test.cpp(180) : see reference to function template instantiation 'void for_each<derived,base1,base2,int,int,fn::<lambda_862ea397905775f7e094cde6fe9b462c>>(CONTAINER *,SIZE (__thiscall base1::* )(void) const,CONTAINED (__thiscall base2::* )(SIZE) const,FUNC &)' being compiled
1>          with
1>          [
1>              CONTAINER=derived
1>  ,            SIZE=int
1>  ,            CONTAINED=int
1>  ,            FUNC=fn::<lambda_862ea397905775f7e094cde6fe9b462c>
1>          ]
1>d:\projects\test\test.cpp(171): error C2064: term does not evaluate to a function taking 1 arguments