C++ 强制 mem_fun 选择特定的重载成员函数
Posted
技术标签:
【中文标题】C++ 强制 mem_fun 选择特定的重载成员函数【英文标题】:C++ forcing mem_fun to select a specific overloaded member function 【发布时间】:2012-03-05 15:55:08 【问题描述】:我实际上已经想出了如何按照我的问题标题所暗示的方式去做,但不是以一种令人满意和便携的方式。让我更具体一点。
这是我的代码的精简和修改版本:
#include <algorithm>
#include <functional>
class A
public:
int my_val() const return _val; ;
int& my_val() throw "Can't do this"; ;
// My class is actually derived from a super class which has both functions, but I don't want A to be able to access this second version
private:
int _val;
std::vector<int> get_int_vector(const std::vector<A*>& a)
std::vector<int> b;
b.reserve(a.size());
transform( a.begin(), a.end(), inserter( b, b.end() ),
std::mem_fun<int, const A>(&A::my_val) );
return b;
现在,我的问题是这段代码在带有 Microsoft Visual Studio C++ 2008 的 Windows 7 中编译和运行良好,但在带有 g++(版本 4.1.2 20080704)的 Red Hat linux 中却没有,我收到以下错误:
error: call of overloaded 'mem_fun(<unresolved overloaded function type>)' is ambiguous
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_function.h:713: note: candidates are: std::mem_fun_t<_Ret, _Tp> std::mem_fun(_Ret (_Tp::*)()) [with _Ret = int, _Tp = const A]
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_function.h:718: note: std::const_mem_fun_t<_Ret, _Tp> std::mem_fun(_Ret (_Tp::*)()const) [with _Ret = int, _Tp = const A]
在 linux 中,如果我将 mem_fun()
调用替换为:mem_fun( static_cast<int (A::*)() const>(&A::my_val) )
,它可以编译并正常工作。然而,我发现这个解决方案不如第一个解决方案美观。有没有另一种便携的方式来做我想做的事? (也许有一种明显简单的方法可以做到这一点,我只是在大惊小怪......)
提前谢谢你。 -曼努埃尔
【问题讨论】:
【参考方案1】:我不确定你的情况,但这对我来说会更令人愉悦。定义你自己的函数:
template <typename S,typename T>
inline std::const_mem_fun_t<S,T> const_mem_fun(S (T::*f)() const)
return std::const_mem_fun_t<S,T>(f);
并像这样使用它:
std::vector<int> get_int_vector(const std::vector<A*>& a)
std::vector<int> b;
b.reserve(a.size());
transform( a.begin(), a.end(), inserter( b, b.end() ),
const_mem_fun(&A::my_val) );
return b;
避免演员表的另一种选择是这样的:
std::vector<int> get_int_vector(const std::vector<A*>& a)
std::vector<int> b;
b.reserve(a.size());
int& (A::*my_val)() const = &A::my_val;
transform( a.begin(), a.end(), inserter( b, b.end() ), std::mem_fun(my_val) );
return b;
【讨论】:
我认为这一点你最好引入 boost bind(或者 std::bind 如果你有它)或者只使用一个循环。 @111111: boost::bind 在这里无济于事,因为真正的问题是,当您将表达式传递给可以解析为多个重载的绑定器时,C++ 没有语法,除了强制转换,以指定要传递的重载。 谢谢 Vaughn,我想这就是我想要的。请注意,您的代码用 g++ 编译,但不能用 MS Visual Studio 编译,它抱怨“错误 C2914: 'const_mem_fun' : cannot deuce template argument as function argument is ambiguous”,所以我必须指定const_mem_fun<int,A>(...)
。
我添加了另一种选择。它不是特别漂亮,但它确实避免了演员表,而且我认为它是便携的。
是的,您的替代方案是可移植的,事实上我一点也不觉得难看。谢谢!【参考方案2】:
typedef int (A::*MethodType)() const;
const_mem_fun(MethodType(&A::my_val));
这就是想法。
【讨论】:
以上是关于C++ 强制 mem_fun 选择特定的重载成员函数的主要内容,如果未能解决你的问题,请参考以下文章
[ C++ ] 类与对象(下)日期类Date补充及流提取和流插入运算符重载