Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ STL中的VS编译器错误C2752(“多个部分专门化匹配”)_C++_Visual C++_Stl - Fatal编程技术网

C++ STL中的VS编译器错误C2752(“多个部分专门化匹配”)

C++ STL中的VS编译器错误C2752(“多个部分专门化匹配”),c++,visual-c++,stl,C++,Visual C++,Stl,不知何故,我喜欢这些“最短”的程序,它们显示了一个(基本的?)问题。在VS2008中测试某些模板代码时,出现了此错误(VS2010和VS2012也已确认此错误,请参见下文): c:\program files(x86)\microsoft visual studio 9.0\vc\include\xmemory(225):错误C2752:“std::\u Ptr\u cat\u helper”:多个部分专门化与模板参数列表匹配 with [ _T1=const floa

不知何故,我喜欢这些“最短”的程序,它们显示了一个(基本的?)问题。在VS2008中测试某些模板代码时,出现了此错误(VS2010和VS2012也已确认此错误,请参见下文):

c:\program files(x86)\microsoft visual studio 9.0\vc\include\xmemory(225):错误C2752:“std::\u Ptr\u cat\u helper”:多个部分专门化与模板参数列表匹配

   with
   [
       _T1=const float (**),
       _T2=const float (**)
   ]
我可以把问题归结为以下三行:

#include <vector>
typedef float TPoint[3];
std::vector<TPoint const*> points; // error C2752
#包括
typedef float TPoint[3];
标准::向量点;//错误C2752
请注意,以下各项都可以

#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;
#包括
#包括
typedef float TPoint[3];
//TPoint的这些类似用法都可以:
标准::向量点;//无误
t点常数*点1[2];
std::列表点2;

我试图通过为struct_Ptr_cat_helper提供额外的模板规范来修复xutility,但运气不好。你知道哪里出了问题吗?或者如何在不丢失
常量的情况下解决问题?

问题确实是部分专门化中的一个模糊问题:

在内部,分配器使用一些元编程(
\u Ptr\u cat
)来确定是否对向量的元素调用dtor(或者什么都不做)。此元编程试图通过使用部分专门化来区分某些情况
\Ptr\u cat
使用
\Ptr\u cat\u helper
这是专门针对向量的分配器的指针类型——向量的
值类型是
t指针常量*==const float(*)[3]
,因此向量的分配器有一个指针类型
常量float(**)[3]

使用
std::vector
时,错误消息包含
[3]
部分,而使用
std::vector
时,
[3]
不显示o.o

\u Ptr\u cat
需要两个具有可能不同c-限定符的相同类型的模板参数,例如
float*、float const*
。 现在,这两种输入类型都是
const float(**)[3]
。MSVC含糊不清地将它们解析为
\u Ptr\u cat\u helper
Ty**,Ty const**
和/或
Ty**,Ty**
。我通过编写一个模拟
\u Ptr\u cat\u helper
部分专门化的小示例验证了这一点(只需简单的模板,不涉及Std库)

然而,我无法解释为什么会发生这种情况。奇怪的是,当只使用一个专门化参数设置一个示例时,并没有歧义--
const float(**)[3]
被解析为
Ty const**
,使用
Ty=float const[3]

多亏了Peter Alexander,我还用g++尝试了我的简单示例(2个模板参数),它按预期工作,没有歧义。也许这是编译器的问题

让我提出一些解决办法:

  • 如果您真的想修改MSVC标准库,可以添加专门化
    \u Ptr\u cat\u helper
    ,它可以精确匹配并解决歧义。不幸的是,您必须显式地提供维度(3)
  • 不要在这里使用数组。使用
    std::array
    (在VS08的
    tr1
    中提供)或结构或普通指针(
    float const*
    而不是
    float const[3]
  • 使用一个简单的包装器:

    template < typename T > struct wrapper { T wrapped; }
    std::vector < wrapper < TPoint > const* > m;
    
    templatestruct wrapper{T wrapped;}
    std::vectorconst*>m;
    
    对我来说很好

编辑:以下是我使用的示例:

#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();
}
#包括
#包括
模板
结构规格
{
静态常量char*check(){返回“普通”;}
typedef无效值;
};
#定义MAKE_规范(ARG0、ARG1)\
模板\
结构规范\
{ \
静态常量char*check(){return#ARG0',“#ARG1;}\
T值\
}
制定规范(T**,T**);
制定规范(T**,T const**);
//可以做得更多,但无需。。
int main()
{
typedef SpecMySpec;

std::我面前不能安装VS,但它可以与GCC一起使用。您可能在他们的标准库中发现了一个错误。升级VS目前是不可能的:我们依赖DLL(使用MFC组件)来自其他组…但是如果听到上面的三行在VS2010上编译,那将是非常棒的。抱歉,它没有编译,这就是我删除该注释的原因。/不过,还不完全清楚向量的元素应该是什么。指向常量浮点的三个元素数组的指针?向量的元素是t中的
float**
他的情况。我正在编写可以处理任何3d点类型(支持特定接口)的模板代码。这些点只分配一次,但在几个容器中引用(不同的排序),因此使用最简单的3d点类型之一进行测试时,
TPoint const*
我得到了上述错误。我在VS08上尝试了你的示例代码,偶然发现了上面提到的类型,与
typeid().name
打印的类型形成对比。将错误中的
const float(**)
const float(**)[3]
进行比较,这是
typeid(TPoint const**)的结果。name()
。额外的间接寻址是由vector的分配器添加的。也许这更像是一个编译器错误而不是库错误?
也许这可能是一个编译器问题
-我希望这是一个库问题。对于分析,仍然+1因为我编写的小示例可以使用g++而不是MSVC编译,我得出结论这不是库问题sue主要是。我已经发现了一些(已确认的)编译器错误,并且知道这些错误非常罕见——因此尝试保守地对其进行表述。嗯?库实现完全不同……我不是说这不可能是编译器问题,但除非你,例如,show GCC+STLPort编译这些错误,而MSV