cop*_*roc 6 c++ stl visual-c++
不知怎的,我喜欢这些"最短"的程序,显示出(基本的?)问题.在VS2008中测试一些模板代码时出现此错误(VS2010和VS2012也已确认,见下文):
c:\ program files(x86)\ microsoft visual studio 9.0\vc\include\xmemory(225):错误C2752:'std :: _ Ptr_cat_helper <_T1,_T2>':多个部分特化匹配模板参数列表
Run Code Online (Sandbox Code Playgroud)with [ _T1=const float (**), _T2=const float (**) ]
我可以将问题归结为以下三行:
#include <vector>
typedef float TPoint[3];
std::vector<TPoint const*> points; // error C2752
Run Code Online (Sandbox Code Playgroud)
请注意,以下都可以
#include <vector>
#include <list>
typedef float TPoint[3];
// these similar usages of TPoint are all ok:
std::vector<TPoint*> points; // no error
TPoint const* points1[2];
std::list<TPoint const*> points2;
Run Code Online (Sandbox Code Playgroud)
我试图通过为struct _Ptr_cat_helper提供额外的模板特性来修复xutility - 没有运气.任何想法出了什么问题?或者如何在不失去的情况下解决const
?
问题确实是部分专业化的含糊不清:
在内部,分配器使用一些元编程(_Ptr_cat
)来确定是否要在向量的元素上调用dtor(或什么都不做).这种元编程试图通过使用部分特化来区分某些情况._Ptr_cat
使用_Ptr_cat_helper
哪个是专门用于向量的分配器的指针类型 - 向量value_type
是TPointer const* == const float (*)[3]
,因此向量的分配器具有指针类型const float(**)[3]
.
使用时std::vector < const float(*)[3] >
,错误消息包含[3]
部分,而使用时std::vector < TPoint const* >
,[3]
不显示oO
_Ptr_cat
期望两个相同类型的模板参数可能具有不同的c-qualifier,例如float*, float const*
.现在,两种输入类型都是const float (**)[3]
.MSVC模糊地解析它们的专业化_Ptr_cat_helper
:Ty**, Ty const**
和/或Ty**, Ty**
.我通过编写一个模仿部分特化的小例子来证实_Ptr_cat_helper
(只是简单的模板,没有涉及Std Lib).
然而,我无法解释为什么会发生这种情况.奇怪的是,有设置只使用一个专门的参数,例如,当没有歧义- const float(**)[3]
被解析为Ty const**
与Ty = float const[3]
预期.
感谢彼得亚历山大,我也用g ++尝试了我的简单示例(2个模板参数),它按预期工作,没有歧义.也许这可能是一个编译器问题?
让我提出一些解决方法:
_Ptr_cat_helper < const Ty (**)[3], const Ty (**)[3] >
完全适合的特殊化并解决歧义.不幸的是,您必须明确提供维度(3).std::array
(tr1
在VS08中可用)或结构或普通指针(float const*
而不是float const[3]
)使用简单的包装器:
template < typename T > struct wrapper { T wrapped; }
std::vector < wrapper < TPoint > const* > m;
Run Code Online (Sandbox Code Playgroud)
对我来说很好.
编辑:这是我用过的例子:
#include <typeinfo>
#include <iostream>
template < typename T1, typename T2 >
struct Spec
{
static const char* check() { return "plain"; }
typedef void Value;
};
#define MAKE_SPEC(ARG0, ARG1) \
template < typename T > \
struct Spec < ARG0, ARG1 > \
{ \
static const char* check() { return #ARG0 ", " #ARG1; } \
typedef T Value; \
}
MAKE_SPEC(T**, T**);
MAKE_SPEC(T**, T const**);
// can do more, but need not to..
int main()
{
typedef Spec < const float(**)[3], const float(**)[3] > MySpec;
std::cout << MySpec::check() << " -- " << typeid(MySpec :: Value).name();
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
986 次 |
最近记录: |