在vc2010中创建指向map值类型成员的指针
Create pointer to member for map value type in vc2010
我们在将代码移植到稍旧的vc++ 2010版本时遇到了问题。
这个问题是由VC中map的实现引起的,它导致non-type-argument
中pointer-to-member
的派生到基的转换是必需的:
#include <map>
#include <algorithm>
template <typename MapValueType, int MapValueType::*var>
bool f (MapValueType const & v);
int main ()
{
typedef std :: map<int, int> MapType;
MapType m;
std :: find_if (m.begin ()
, m.end ()
, f<MapType::value_type, & MapType::value_type::second> );
}
生成以下消息:
从基类的指针到成员到派生类的指针到成员的标准转换不适用于模板实参file.cc(x):'f':无效模板参数'int std::_Pair_base<_Ty1,_Ty2>::* '
因此,value_type
在std::map
中的实现似乎在基类中有对。
关于如何解决这个和保持pointer-to-member
作为non-type-argument
的想法吗?
我们唯一的选择是改变结构,使f
是functor
与pointer-to-member
成员吗?
为什么坚持将指向成员的指针作为非类型模板形参/实参?
无论如何,我认为你可以使用这个,如果你可以限制在Visual Studio 2010或编译器与decltype()
template <typename Class, typename Type>
Class
get_class_type (Type Class:: *);
//...
it = std::find_if(m.begin(), m.end(),
f<decltype(get_class_type(&MapType::value_type::second)), &MapType::value_type::second>);
假设你的代码应该编译IMO(在GCC 4.7.2和Clang 3.2上确实如此),我相信你的设计是不必要的复杂。pair
只有两个成员变量,因此您将访问第一个或第二个。
我也不认为需要一个函子对象:只需使用一个布尔模板实参来确定代码是在first
成员变量上工作还是在second
成员变量上工作。这里有一个可能性:
#include <map>
#include <algorithm>
template <typename MapValueType, bool first>
bool f (MapValueType const & p)
{
auto& v = (first) ? p.first : p.second;
// ... do your work on v ...
}
int main ()
{
typedef std :: map<int, int> MapType;
MapType m;
// Will work on the `first` member
std::find_if(m.begin (), m.end (), f<MapType::value_type, true>);
// Will work on the `second` member
std::find_if(m.begin (), m.end (), f<MapType::value_type, false>);
}
如果你真的不能改变你的客户端代码或f()
函数中的代码,那么你可以使用这个vs2010特定的hack:
// Add "_MyBase" here... works, but ugly IMO
template <typename MapValueType, int MapValueType::_Mybase::* var>
bool f(MapValueType const & v);
// And the client side could stay unchanged...
int main ()
{
typedef std :: map<int, int> MapType;
MapType m;
std::find_if(
m.begin(),
m.end (),
f<MapType::value_type, &MapType::value_type::second>
);
}
最后,如果您的代码必须在其他平台上编译和,那么对函数和客户端代码的不可修改性的所有约束仍然存在,那么您可以定义一个预处理器宏,扩展到VS2010的_Mybase::
和其他编译器的空字符串。
- 访问C++中的类型成员
- 具有 STL 向量类型成员的类的复制内存
- 重载具有 2 个相同数据类型成员的构造函数
- std::void_t 和嵌套的非类型成员
- 返回对常量结构(指针类型)成员的引用:明显的左值到右值转换
- 使用各种数据类型成员创建对象的简便方法
- 将类类型成员定义为公共和私有之间有什么区别?
- 结构类型成员的默认构造函数中的默认参数
- 如何传递模板模板非类型成员函数指针
- 文本类类型成员函数约束
- 给定仅包含布尔类型成员的结构的两个对象 s1 和 s2,只要 s1 的成员为 true,请检查 s2 的每个成员是否为真
- 如何在 c++ 中使用二进制文件输入/输出读取/写入结构的字符串类型成员
- C++:将模板参数的模板类型成员加为好友的语法正确吗
- C++静态结构类型成员初始化
- C++:作为引用或指针的基类型成员变量
- 左值引用类型成员的用户定义移动构造函数
- 具有指针类型成员的类在 MSVS2012@debug 下销毁时失败.程序错误或错误源
- CRTP -- 访问不完整的类型成员
- 为什么C++默认初始化不对非类类型成员进行零初始化
- 请求非类类型成员