我们在将代码移植到稍微不太老的VC++ 2010版本时遇到了问题。
造成这些问题的原因是在VC中实现了map,这导致需要在non-type-argument中将non-type-argument派生为基本转换:
#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):错误C2973:'f‘:无效的模板参数'int std::_Pair_base<_Ty1,_Ty2>::*’,不应用从指针到基的指针到派生的成员的标准转换。
因此,value_type在std::map中的实现似乎是基类中的一对。
关于如何解决这一问题并将pointer-to-member保持为non-type-argument的任何想法
是更改结构的唯一选项,以便f是具有成员pointer-to-member的functor。
发布于 2013-01-21 14:38:20
如果你的代码应该编译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()函数中的代码,那么您可以选择以下If 2010特定的黑客:
// 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>
);
}最后,如果您的代码必须在其他平台上编译,并且函数和客户端代码的不可修改性上的所有约束仍然有效,那么您可以定义一个预处理器宏,该宏扩展为_Mybase:: for VS2010,并扩展到其他编译器的空字符串。
发布于 2013-01-21 14:26:40
为什么坚持将指向成员的指针保留为非类型模板参数/参数?
无论如何,我认为您可以使用这个,如果您可以限制在Visual 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>);https://stackoverflow.com/questions/14439921
复制相似问题