2012-10-06 14 views
6

Bir şekilde bu "en kısa" programları (temel?) Sorununu beğeniyorum.VS derleyici hatası C2752 ("birden fazla kısmi uzmanlık eşleşmesi"), STL'de

c: VS2008 bazı şablon kodunu test edilirken bu hata (aşağıya bakınız aynı zamanda VS2010 ve VS2012 onaylandı) geldi \ program dosyaları (x86) \ microsoft visual studio 9.0 \ vc \ include \ xmemory (225): hata C2752: 'standart :: _ Ptr_cat_helper < _T1, _T2>': birden fazla kısmi uzmanlık aşağıdaki üç satır sorunu aşağı kaynatın

with 
    [ 
     _T1=const float (**), 
     _T2=const float (**) 
    ] 

şablon bağımsız değişken listesi

eşleşen :

#include <vector> 
typedef float TPoint[3]; 
std::vector<TPoint const*> points; // error C2752 
Şans olmadan - Aşağıdaki o

Not ben yapı _Ptr_cat_helper için ek şablon spezializations sağlayarak xutility düzeltmeye çalıştı tüm Tamam

#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; 

olduğunu. Herhangi bir fikir yanlış giden nedir? Veya const'u kaybetmeden nasıl çalışırsınız?

Dahili olarak, ayırıcı dtor vektörünün unsurları çağrılacak olup olmadığını belirlemek (ya da hiçbir şey) bazı metaprogramming (_Ptr_cat) kullanır:

+1

VS önümde yüklemek yok mu, ama GCC ile çalışır. Standart lib'lerinde bir hata bulmuş olabilirsiniz. –

+0

Upgrading VS şu anda mümkün değil: dlls'e (MFC bileşenlerini kullanarak) diğer gruplardan bağlıyız ... Ama yukarıdaki üç satırın VS2010 – coproc

+0

derlemesini derlemediğini duymak harika olurdu, bu yüzden derlemedim, yorum kaldırıldı. :/Vektörün elementinin ne olması gerektiği tamamen açık değil. Const üç elemanların bir dizi için bir işaretçi yüzüyor? – Xeo

cevap

8

sorun gerçekten de kısmi uzmanlık bir belirsizlik olduğu. Bu meta programlama, bazı durumları kısmi uzmanlık kullanarak ayırt etmeye çalışır. _Ptr_cat, _Ptr_cat_helper numaralı telefonun value_type numaralı TPointer const* == const float (*)[3] numaralı vektörü üzerinde uzmanlaşmış olup, const float(**)[3] işaretçisinin türünde bir işaretçiye sahiptir.

Eğer std::vector < const float(*)[3] > kullanmak

, hata iletisi [3]

_Ptr_cat muhtemelen farklı Cı-eleme, örneğin aynı türden iki şablon bağımsız değişkenler bekler o.o

görüntülenmez, std::vector < TPoint const* > kullanarak ise, [3] kısmını içeren float*, float const*. Şimdi, iki giriş türü hem const float (**)[3]. MSVC _Ptr_cat_helper uzmanlık alanlarına muğlak onları giderir: Ty**, Ty const** ve/veya Ty**, Ty**. _Ptr_cat_helper'un kısmi uzmanlığını taklit eden küçük bir örnek yazarak bunu doğruladım (sadece düz şablonlar, Std Lib dahil değil). Yine de bunun neden olduğunu açıklayamıyorum. Garip bir şekilde, yalnızca bir uzmanlık parametresi kullanarak bir örnek oluştururken belirsizlik olmaz - const float(**)[3], Ty = float const[3] ile beklendiği gibi Ty const** ile çözülür.

Peter Alexander sayesinde, basit örneğimi (2 şablon parametresi) g ++ ile denedim ve beklendiği gibi çalıştı, belirsizlik yoktu. Belki bu derleyici bir sorun olabilir?

bana bazı geçici çözümler önermek yapalım:
  • gerçekten MSVC standart lib değiştirmek istiyorsanız

    , bir ihtisas tam oturur ve belirsizliği ortadan kaldırmaktadır _Ptr_cat_helper < const Ty (**)[3], const Ty (**)[3] > ekleyebilir. Maalesef, boyutu açıkça belirtmelisiniz (3).
  • dizilerini burada kullanmayın.

    template < typename T > struct wrapper { T wrapped; } 
    std::vector < wrapper <TPoint> const* > m; 
    

    benim için çalışıyor: ya yapıların veya düz işaretçiler (yerine float const[3] ait float const*)

  • basit sarmalayıcı kullan (VS08 içinde tr1 mevcut) std::array kullanın.

Düzenleme: Burada kullandığım örnek:

#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(); 
} 
+0

'Belki bu bir derleyici sorunu olabilir - o zaman bir kütüphane sorunu olmasını beklerdim. Analiz için hala +1 – sehe

+0

Yazdığım küçük örnek g ++ ile ve MSVC ile değil, iyi derlediği için, bunun öncelikli olarak kütüphane konusu olmadığı sonucuna varıyorum. Zaten bazı (onaylanmış) derleyici hatalarına rastladım ve bunların gerçekten nadir olduğunu biliyorum - bu yüzden onu muhafazakar bir şekilde formüle etmeye çalışıyorum. – dyp

+1

Huh? Kütüphane uygulamaları tamamen farklı ... Ben derleyici bir sorun olamayacağını söylemiyorum, ancak siz, örneğin, GCC + STLPort bunu derlediğini gösterene kadar, MSVC + STLPort henüz küçük bir vakfa sahip değilsiniz – sehe

İlgili konular